From 68a8efea502cd7c086f26a4b4c93fd8ea5dd4fdc Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 9 Apr 2018 15:50:03 -0400 Subject: [PATCH] PR c++/85264 - ICE with excess template-parameter-list. * parser.c (cp_parser_check_template_parameters): Add template_id_p parameter. Don't allow an extra template header if true. (cp_parser_class_head): Pass template_id_p. (cp_parser_elaborated_type_specifier): Likewise. (cp_parser_alias_declaration): Likewise. (cp_parser_check_declarator_template_parameters): Likewise. From-SVN: r259253 --- gcc/cp/ChangeLog | 10 ++++++++++ gcc/cp/parser.c | 22 ++++++++++++++++------ gcc/testsuite/g++.dg/cpp0x/variadic176.C | 10 ++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic176.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index deac522..f55a240 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2018-04-09 Jason Merrill + + PR c++/85264 - ICE with excess template-parameter-list. + * parser.c (cp_parser_check_template_parameters): Add template_id_p + parameter. Don't allow an extra template header if true. + (cp_parser_class_head): Pass template_id_p. + (cp_parser_elaborated_type_specifier): Likewise. + (cp_parser_alias_declaration): Likewise. + (cp_parser_check_declarator_template_parameters): Likewise. + 2018-04-09 Jakub Jelinek PR c++/85194 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 9c8a886..d4b62c7 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2498,7 +2498,7 @@ static tree cp_parser_maybe_treat_template_as_class static bool cp_parser_check_declarator_template_parameters (cp_parser *, cp_declarator *, location_t); static bool cp_parser_check_template_parameters - (cp_parser *, unsigned, location_t, cp_declarator *); + (cp_parser *, unsigned, bool, location_t, cp_declarator *); static cp_expr cp_parser_simple_cast_expression (cp_parser *); static tree cp_parser_global_scope_opt @@ -17923,6 +17923,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, if (template_parm_lists_apply && !cp_parser_check_template_parameters (parser, /*num_templates=*/0, + /*template_id*/false, token->location, /*declarator=*/NULL)) return error_mark_node; @@ -18977,6 +18978,7 @@ cp_parser_alias_declaration (cp_parser* parser) if (parser->num_template_parameter_lists && !cp_parser_check_template_parameters (parser, /*num_templates=*/0, + /*template_id*/false, id_location, /*declarator=*/NULL)) return error_mark_node; @@ -23123,6 +23125,7 @@ cp_parser_class_head (cp_parser* parser, /* Make sure that the right number of template parameters were present. */ if (!cp_parser_check_template_parameters (parser, num_templates, + template_id_p, type_start_token->location, /*declarator=*/NULL)) { @@ -26397,17 +26400,22 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, { unsigned num_templates = 0; tree scope = declarator->u.id.qualifying_scope; + bool template_id_p = false; if (scope) num_templates = num_template_headers_for_class (scope); else if (TREE_CODE (declarator->u.id.unqualified_name) == TEMPLATE_ID_EXPR) - /* If the DECLARATOR has the form `X' then it uses one - additional level of template parameters. */ - ++num_templates; + { + /* If the DECLARATOR has the form `X' then it uses one + additional level of template parameters. */ + ++num_templates; + template_id_p = true; + } return cp_parser_check_template_parameters - (parser, num_templates, declarator_location, declarator); + (parser, num_templates, template_id_p, declarator_location, + declarator); } case cdk_function: @@ -26436,6 +26444,7 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, static bool cp_parser_check_template_parameters (cp_parser* parser, unsigned num_templates, + bool template_id_p, location_t location, cp_declarator *declarator) { @@ -26445,7 +26454,8 @@ cp_parser_check_template_parameters (cp_parser* parser, return true; /* If there are more, but only one more, then we are referring to a member template. That's OK too. */ - if (parser->num_template_parameter_lists == num_templates + 1) + if (!template_id_p + && parser->num_template_parameter_lists == num_templates + 1) return true; /* If there are more template classes than parameter lists, we have something like: diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic176.C b/gcc/testsuite/g++.dg/cpp0x/variadic176.C new file mode 100644 index 0000000..1d6e3c2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic176.C @@ -0,0 +1,10 @@ +// PR c++/85264 +// { dg-do compile { target c++11 } } + +template struct A {}; + +template +template +struct A {}; // { dg-error "too many template-parameter-lists" } + +A a; -- 2.7.4