aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-04-09 15:50:03 -0400
committerJason Merrill <jason@gcc.gnu.org>2018-04-09 15:50:03 -0400
commit68a8efea502cd7c086f26a4b4c93fd8ea5dd4fdc (patch)
tree53b9d4e2e4cafdd85f18ee47c7fdbd72e4550e77 /gcc
parent6e4f1148ce233f2533d56ab20dc002dc1e9a83d7 (diff)
downloadgcc-68a8efea502cd7c086f26a4b4c93fd8ea5dd4fdc.zip
gcc-68a8efea502cd7c086f26a4b4c93fd8ea5dd4fdc.tar.gz
gcc-68a8efea502cd7c086f26a4b4c93fd8ea5dd4fdc.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/parser.c22
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic176.C10
3 files changed, 36 insertions, 6 deletions
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 <jason@redhat.com>
+
+ 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 <jakub@redhat.com>
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<y>' then it uses one
- additional level of template parameters. */
- ++num_templates;
+ {
+ /* If the DECLARATOR has the form `X<y>' 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<typename> struct A {};
+
+template<int>
+template<typename... T>
+struct A<void(T...)> {}; // { dg-error "too many template-parameter-lists" }
+
+A<void(int)> a;