1) There's a function to count how many template headers we should
have, we should use it.

2) While working on something a while back I ran into trying to
instantiate a nested function while still in processing_template_decl
context, which doesn't work so well.  Let's check for that.

3) A predicate asking about user-provided functions should use
user_provided_p, not DECL_ARTIFICIAL.

4) A minor simplification of the this-capture logic.

5) Correcting wrong uses of "argument" vs. "parameter".

Tested x86_64-pc-linux-gnu, applying to trunk.
commit aad1656a3f0296ea99d79272f5d639f1a83b767c
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Apr 9 13:57:42 2018 -0400

    * parser.c (cp_parser_class_head): Use num_template_headers_for_class.

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 88db9988bd4..82b8ef87ed7 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -22930,20 +22930,7 @@ cp_parser_class_head (cp_parser* parser,
       /* Otherwise, count the number of templates used in TYPE and its
 	 containing scopes.  */
       else
-	{
-	  tree scope;
-
-	  for (scope = TREE_TYPE (type);
-	       scope && TREE_CODE (scope) != NAMESPACE_DECL;
-	       scope = get_containing_scope (scope))
-	    if (TYPE_P (scope)
-		&& CLASS_TYPE_P (scope)
-		&& CLASSTYPE_TEMPLATE_INFO (scope)
-		&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope))
-		&& (!CLASSTYPE_TEMPLATE_SPECIALIZATION (scope)
-		    || uses_template_parms (CLASSTYPE_TI_ARGS (scope))))
-	      ++num_templates;
-	}
+	num_templates = num_template_headers_for_class (TREE_TYPE (type));
     }
   /* Otherwise, the identifier is optional.  */
   else
commit c6b45dd7a70decb3fbd75f72d1f33b30e156e150
Author: Jason Merrill <ja...@redhat.com>
Date:   Tue Mar 13 16:07:04 2018 -0400

    Make sure we aren't trying to do a nested instantiation in template context.
    
            * pt.c (instantiate_decl): Make sure we aren't trying to do a nested
            instantiation in template context.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e8346d3bf58..790d6ea25e9 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -23886,6 +23886,7 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p)
     push_to_top_level ();
   else
     {
+      gcc_assert (!processing_template_decl);
       push_function_context ();
       cp_unevaluated_operand = 0;
       c_inhibit_evaluation_warnings = 0;
commit df63e4ead6154887682fba12299ae414a12f49e6
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Mar 12 13:56:49 2018 -0400

    * class.c (vbase_has_user_provided_move_assign): Use user_provided_p.

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 0427d1224f7..30323f0a9f6 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5017,7 +5017,7 @@ vbase_has_user_provided_move_assign (tree type)
     for (ovl_iterator iter (get_class_binding_direct
 			    (type, assign_op_identifier));
 	 iter; ++iter)
-      if (!DECL_ARTIFICIAL (*iter) && move_fn_p (*iter))
+      if (user_provided_p (*iter) && move_fn_p (*iter))
 	return true;
 
   /* Do any of its bases?  */
commit 0114f237348ab82d75d2277452926fa897b24dab
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Mar 5 17:41:26 2018 -0500

            * lambda.c (lambda_expr_this_capture): Improve logic.

diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index e9b962a8f33..e3f22fcc5b9 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -743,9 +743,7 @@ lambda_expr_this_capture (tree lambda, bool add_capture_p)
     add_capture_p = false;
 
   /* Try to default capture 'this' if we can.  */
-  if (!this_capture
-      && (!add_capture_p
-          || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE))
+  if (!this_capture)
     {
       tree lambda_stack = NULL_TREE;
       tree init = NULL_TREE;
@@ -756,9 +754,15 @@ lambda_expr_this_capture (tree lambda, bool add_capture_p)
            3. a non-default capturing lambda function.  */
       for (tree tlambda = lambda; ;)
 	{
-          lambda_stack = tree_cons (NULL_TREE,
-                                    tlambda,
-                                    lambda_stack);
+	  if (add_capture_p
+	      && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (tlambda) == CPLD_NONE)
+	    /* tlambda won't let us capture 'this'.  */
+	    break;
+
+	  if (add_capture_p)
+	    lambda_stack = tree_cons (NULL_TREE,
+				      tlambda,
+				      lambda_stack);
 
 	  tree closure = LAMBDA_EXPR_CLOSURE (tlambda);
 	  tree containing_function
@@ -807,10 +811,6 @@ lambda_expr_this_capture (tree lambda, bool add_capture_p)
 	      init = LAMBDA_EXPR_THIS_CAPTURE (tlambda);
 	      break;
 	    }
-
-	  if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (tlambda) == CPLD_NONE)
-	    /* An outer lambda won't let us capture 'this'.  */
-	    break;
 	}
 
       if (init)
commit fb725d091432d694c1d565710691bda335f38146
Author: Jason Merrill <ja...@redhat.com>
Date:   Fri Feb 9 17:25:24 2018 -0500

            * decl.c (make_typename_type): s/parameters/arguments/.
    
            * parser.c (cp_parser_nested_name_specifier_opt): Likewise.
            * pt.c (make_pack_expansion): Correct error message.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index fccddd54d69..d58964754b9 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3756,7 +3756,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
   if (TREE_CODE (name) == TEMPLATE_DECL)
     {
       if (complain & tf_error)
-	error ("%qD used without template parameters", name);
+	error ("%qD used without template arguments", name);
       return error_mark_node;
     }
   gcc_assert (identifier_p (name));
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index f8ecf030c0d..88db9988bd4 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -6346,7 +6346,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
 						    token->location);
 		      if (TREE_CODE (decl) == TEMPLATE_DECL)
 			error_at (token->location,
-				  "%qD used without template parameters",
+				  "%qD used without template arguments",
 				  decl);
 		      else if (ambiguous_decls)
 			{
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 180dfd6861c..e8346d3bf58 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -4007,9 +4007,9 @@ make_pack_expansion (tree arg, tsubst_flags_t complain)
       if (complain & tf_error)
 	{
 	  if (TYPE_P (arg))
-	    error ("expansion pattern %qT contains no argument packs", arg);
+	    error ("expansion pattern %qT contains no parameter packs", arg);
 	  else
-	    error ("expansion pattern %qE contains no argument packs", arg);
+	    error ("expansion pattern %qE contains no parameter packs", arg);
 	}
       return error_mark_node;
     }
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas9.C b/gcc/testsuite/g++.dg/cpp0x/alignas9.C
index 98fe7077582..05d15ffe40b 100644
--- a/gcc/testsuite/g++.dg/cpp0x/alignas9.C
+++ b/gcc/testsuite/g++.dg/cpp0x/alignas9.C
@@ -2,5 +2,5 @@
 // { dg-do compile { target c++11 } }
 
 template <typename... T>
-struct A { alignas(int...) char c; }; // { dg-error "no argument packs|expected" }
+struct A { alignas(int...) char c; }; // { dg-error "no parameter packs|expected" }
 A<int, double> a;
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex13.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex13.C
index 105208701bf..ca7ed33ac02 100644
--- a/gcc/testsuite/g++.dg/cpp0x/variadic-ex13.C
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex13.C
@@ -32,7 +32,7 @@ template<typename... Args> void f(Args...);
 template<typename... Args> void g(Args... args) 
 {
    f(const_cast<const Args*>(&args)...); // okay: ``Args'' and ``args'' are expanded
-   f(5 ...); // { dg-error "contains no argument packs" }
+   f(5 ...); // { dg-error "contains no parameter packs" }
    f(args); // { dg-error "5:parameter packs not expanded" }
    // { dg-message "args" "note" { target *-*-* } .-1 }
    f(h(args...) + args...); // okay: first ``args'' expanded within h, second ``args'' expanded within f.
diff --git a/gcc/testsuite/g++.dg/template/type1.C b/gcc/testsuite/g++.dg/template/type1.C
index b74d975ac49..0191ae55dfc 100644
--- a/gcc/testsuite/g++.dg/template/type1.C
+++ b/gcc/testsuite/g++.dg/template/type1.C
@@ -4,5 +4,5 @@ struct A {
   template <class T> struct B { static int c; };
 };
 
-int A::B::c;			// { dg-error "parameters" }
+int A::B::c;			// { dg-error "arguments" }
 int A::C::d;			// { dg-error "declared" }

Reply via email to