diff mbox

New C++ PATCH for c++/10200 et al

Message ID ce850d11-48b9-1761-372a-e643a25de595@redhat.com
State New
Headers show

Commit Message

Jason Merrill May 19, 2016, 7:14 p.m. UTC
On 05/18/2016 01:42 PM, Jason Merrill wrote:
> On 05/13/2016 03:17 PM, Jason Merrill wrote:
>> On 02/16/2016 07:49 PM, Jason Merrill wrote:
>>> Clearly the DR 141 change is requiring much larger adjustments in the
>>> rest of the compiler than I'm comfortable making at this point in the
>>> GCC 6 schedule, so I'm backing out my earlier changes for 10200 and
>>> 69753 and replacing them with a more modest fix for 10200: Now we will
>>> still find member function templates by unqualified lookup, we just
>>> won't find namespace-scope function templates.  The earlier approach
>>> will return in GCC 7 stage 1.
>>
>> As promised.  The prerequisite for the DR 141 change was fixing the
>> C++11 handling of type-dependence of member access expressions,
>> including calls.  14.6.2.2 says,
>>
>> A class member access expression (5.2.5) is type-dependent if the
>> expression refers to a member of the current instantiation and the type
>> of the referenced member is dependent, or the class member access
>> expression refers to a member of an unknown specialization. [ Note: In
>> an expression of the form x.y or xp->y the type of the expression is
>> usually the type of the member y of the class of x (or the class pointed
>> to by xp). However, if x or xp refers to a dependent type that is not
>> the current instantiation, the type of y is always dependent. If x or xp
>> refers to a non-dependent type or refers to the current instantiation,
>> the type of y is the type of the class member access expression. —end
>> note ]
>>
>> Previously we had been treating such expressions as type-dependent if
>> the object-expression is type-dependent, even if its type is the current
>> instantiation.  Fixing this required a few changes in other areas that
>> now have to deal with non-dependent member function calls within a
>> template.
>
> A small tweak to handling of value-dependent functions to better match
> the text of the standard.

And some other places that needed to be updated to handle multiple 
levels of template args due to non-dependent member function calls.

Jason
diff mbox

Patch

commit 19e3a881e67edf3181b33cb064e9fea699aba8c9
Author: Jason Merrill <jason@redhat.com>
Date:   Wed May 18 16:52:58 2016 -0400

    	Fix handling of non-dependent calls with default template args.
    
    	PR c++/10200
    	* pt.c (fn_type_unification): Add outer template args if needed.
    	(type_unification_real): Handle getting full args.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index fde3091..3908592 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -17578,6 +17578,13 @@  fn_type_unification (tree fn,
   tree tinst;
   tree r = error_mark_node;
 
+  tree full_targs = targs;
+  if (TMPL_ARGS_DEPTH (targs)
+      < TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (fn)))
+    full_targs = (add_outermost_template_args
+		  (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (fn)),
+		   targs));
+
   if (decltype_p)
     complain |= tf_decltype;
 
@@ -17623,6 +17630,14 @@  fn_type_unification (tree fn,
       location_t loc = input_location;
       bool incomplete = false;
 
+      if (explicit_targs == error_mark_node)
+	goto fail;
+
+      if (TMPL_ARGS_DEPTH (explicit_targs)
+	  < TMPL_ARGS_DEPTH (full_targs))
+	explicit_targs = add_outermost_template_args (full_targs,
+						      explicit_targs);
+
       /* Adjust any explicit template arguments before entering the
 	 substitution context.  */
       explicit_targs
@@ -17702,6 +17717,7 @@  fn_type_unification (tree fn,
 	goto fail;
 
       /* Place the explicitly specified arguments in TARGS.  */
+      explicit_targs = INNERMOST_TEMPLATE_ARGS (explicit_targs);
       for (i = NUM_TMPL_ARGS (explicit_targs); i--;)
 	TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (explicit_targs, i);
     }
@@ -17751,7 +17767,7 @@  fn_type_unification (tree fn,
   checks = NULL;
 
   ok = !type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
-			       targs, parms, args, nargs, /*subr=*/0,
+			       full_targs, parms, args, nargs, /*subr=*/0,
 			       strict, flags, &checks, explain_p);
   if (!explain_p)
     pop_tinst_level ();
@@ -18247,7 +18263,7 @@  unify_one_argument (tree tparms, tree targs, tree parm, tree arg,
 
 static int
 type_unification_real (tree tparms,
-		       tree targs,
+		       tree full_targs,
 		       tree xparms,
 		       const tree *xargs,
 		       unsigned int xnargs,
@@ -18270,6 +18286,8 @@  type_unification_real (tree tparms,
   gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
   gcc_assert (ntparms > 0);
 
+  tree targs = INNERMOST_TEMPLATE_ARGS (full_targs);
+
   /* Reset the number of non-defaulted template arguments contained
      in TARGS.  */
   NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs) = NULL_TREE;
@@ -18304,7 +18322,7 @@  type_unification_real (tree tparms,
       arg = args[ia];
       ++ia;
 
-      if (unify_one_argument (tparms, targs, parm, arg, subr, strict,
+      if (unify_one_argument (tparms, full_targs, parm, arg, subr, strict,
 			      explain_p))
 	return 1;
     }
@@ -18324,7 +18342,7 @@  type_unification_real (tree tparms,
 
       /* Copy the parameter into parmvec.  */
       TREE_VEC_ELT (parmvec, 0) = TREE_VALUE (parms);
-      if (unify_pack_expansion (tparms, targs, parmvec, argvec, strict,
+      if (unify_pack_expansion (tparms, full_targs, parmvec, argvec, strict,
                                 /*subr=*/subr, explain_p))
         return 1;
 
@@ -18485,8 +18503,8 @@  type_unification_real (tree tparms,
 	  location_t save_loc = input_location;
 	  if (DECL_P (parm))
 	    input_location = DECL_SOURCE_LOCATION (parm);
-	  arg = tsubst_template_arg (arg, targs, complain, NULL_TREE);
-	  arg = convert_template_argument (parm, arg, targs, complain,
+	  arg = tsubst_template_arg (arg, full_targs, complain, NULL_TREE);
+	  arg = convert_template_argument (parm, arg, full_targs, complain,
 					   i, NULL_TREE);
 	  input_location = save_loc;
 	  *checks = get_deferred_access_checks ();
diff --git a/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg6.C b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg6.C
new file mode 100644
index 0000000..1e0dc54
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg6.C
@@ -0,0 +1,7 @@ 
+// { dg-do compile { target c++11 } }
+
+template <class T>
+struct A {
+  template <int I = 42, int J = (T)42> int f() { return I; }
+  template <int I = 42> int g() { return f(); }
+};