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" }