diff mbox

[C++,Patch/RFC] PR 60608

Message ID 53C40355.3090100@oracle.com
State New
Headers show

Commit Message

Paolo Carlini July 14, 2014, 4:20 p.m. UTC
Hi,

I have been looking a bit into this bug, using a reduced testcase which 
simplifies the debugging quite a bit for me (a non-variadic variant is 
ok). I cannot say to already understand all the details of the issue, 
but something which strikes me as interesting, is that the DEDUCE_CALL 
passed down by add_candidate gets lost and we end up calling 
type_unification_real from unify with DEDUCE_EXACT. If I change it to an 
unconditional DEDUCE_CALL, the testcase is accepted and the testsuite 
passes with no regressions. Is that all there is to the issue?!?

Thanks!
Paolo.

////////////////////

Comments

Jason Merrill July 14, 2014, 7:47 p.m. UTC | #1
On 07/14/2014 12:20 PM, Paolo Carlini wrote:
> I have been looking a bit into this bug, using a reduced testcase which
> simplifies the debugging quite a bit for me (a non-variadic variant is
> ok). I cannot say to already understand all the details of the issue,
> but something which strikes me as interesting, is that the DEDUCE_CALL
> passed down by add_candidate gets lost and we end up calling
> type_unification_real from unify with DEDUCE_EXACT. If I change it to an
> unconditional DEDUCE_CALL, the testcase is accepted and the testsuite
> passes with no regressions. Is that all there is to the issue?!?

Unfortunately, that goes too far.  I think we want a new DEDUCE_PARMS 
that is like DEDUCE_EXACT but does the same transformations as 
tsubst_arg_types in this part of unify_pack_expansion:

>       /* If we had explicit template arguments, substitute them into the
>          pattern before deduction.  */
>       if (any_explicit)
>         {
>           /* Some arguments might still be unspecified or dependent.  */
>           bool dependent;
>           ++processing_template_decl;
>           dependent = any_dependent_template_arguments_p (targs);
>           if (!dependent)
>             --processing_template_decl;
>           parm = tsubst (pattern, targs,
>                          explain_p ? tf_warning_or_error : tf_none,
>                          NULL_TREE);
>           if (dependent)
>             --processing_template_decl;
>           if (parm == error_mark_node)
>             return 1;
>         }

Jason
Paolo Carlini July 14, 2014, 9:12 p.m. UTC | #2
Hi,

On 07/14/2014 09:47 PM, Jason Merrill wrote:
> On 07/14/2014 12:20 PM, Paolo Carlini wrote:
>> I have been looking a bit into this bug, using a reduced testcase which
>> simplifies the debugging quite a bit for me (a non-variadic variant is
>> ok). I cannot say to already understand all the details of the issue,
>> but something which strikes me as interesting, is that the DEDUCE_CALL
>> passed down by add_candidate gets lost and we end up calling
>> type_unification_real from unify with DEDUCE_EXACT. If I change it to an
>> unconditional DEDUCE_CALL, the testcase is accepted and the testsuite
>> passes with no regressions. Is that all there is to the issue?!?
>
> Unfortunately, that goes too far.  I think we want a new DEDUCE_PARMS 
> that is like DEDUCE_EXACT but does the same transformations as 
> tsubst_arg_types in this part of unify_pack_expansion:

Thanks. This helps me a lot. In particular I see now, in tsubst_arg_types:

     /* Do array-to-pointer, function-to-pointer conversion, and ignore
        top-level qualifiers as required.  */
     type = cv_unqualified (type_decays_to (type));

which is exactly the ingredient we are missing. A rough draft already 
appears to work on the testcase, now I have only to figure out what 
happens of the various switches over unification_kind_t and adjust the 
other details (also, comments).

Thanks again,
Paolo.
Jason Merrill July 14, 2014, 9:21 p.m. UTC | #3
On 07/14/2014 05:12 PM, Paolo Carlini wrote:
> Thanks. This helps me a lot. In particular I see now, in tsubst_arg_types:
>
>      /* Do array-to-pointer, function-to-pointer conversion, and ignore
>         top-level qualifiers as required.  */
>      type = cv_unqualified (type_decays_to (type));
>
> which is exactly the ingredient we are missing.

I think we probably want to share the void and abstract checks too.

Jason
diff mbox

Patch

Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 212510)
+++ cp/pt.c	(working copy)
@@ -18198,7 +18198,7 @@  unify (tree tparms, tree targs, tree parm, tree ar
 	nargs = i;
 
 	return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
-				      args, nargs, 1, DEDUCE_EXACT,
+				      args, nargs, 1, DEDUCE_CALL,
 				      LOOKUP_NORMAL, NULL, explain_p);
       }
 
Index: testsuite/g++.dg/cpp0x/variadic161.C
===================================================================
--- testsuite/g++.dg/cpp0x/variadic161.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/variadic161.C	(working copy)
@@ -0,0 +1,14 @@ 
+// PR c++/60608
+// { dg-do compile { target c++11 } }
+
+template<typename... Args>
+void
+wrapper(void (*)(Args...));
+
+void myfun(int);
+
+void
+test()
+{
+  wrapper<const int>(myfun);
+}