From: Adam Butcher Date: Thu, 26 Jun 2014 05:12:52 +0000 (+0100) Subject: re PR c++/61537 (template parameter lists wrongly detected on "struct" or "class... X-Git-Tag: releases/gcc-5.1.0~6655 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2626fc495bb50774416896f898914977a5071d29;p=thirdparty%2Fgcc.git re PR c++/61537 (template parameter lists wrongly detected on "struct" or "class" keyword on parameters) Fix PR c++/61537 * parser.c (cp_parser_elaborated_type_specifier): Only consider template parameter lists outside of function parameter scope. * g++.dg/template/pr61537.C: New testcase. From-SVN: r212008 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c3d520e3923e..124f4d6e30bd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2014-06-26 Adam Butcher + + PR c++/61537 + * parser.c (cp_parser_elaborated_type_specifier): Only consider template + parameter lists outside of function parameter scope. + 2014-06-25 Paolo Carlini DR 178 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 41200a02fb0c..c440c9937bab 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -15081,6 +15081,18 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, return cp_parser_make_typename_type (parser, parser->scope, identifier, token->location); + + /* Template parameter lists apply only if we are not within a + function parameter list. */ + bool template_parm_lists_apply + = parser->num_template_parameter_lists; + if (template_parm_lists_apply) + for (cp_binding_level *s = current_binding_level; + s && s->kind != sk_template_parms; + s = s->level_chain) + if (s->kind == sk_function_parms) + template_parm_lists_apply = false; + /* Look up a qualified name in the usual way. */ if (parser->scope) { @@ -15123,7 +15135,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, decl = (cp_parser_maybe_treat_template_as_class (decl, /*tag_name_p=*/is_friend - && parser->num_template_parameter_lists)); + && template_parm_lists_apply)); if (TREE_CODE (decl) != TYPE_DECL) { @@ -15136,9 +15148,9 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, if (TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE) { - bool allow_template = (parser->num_template_parameter_lists - || DECL_SELF_REFERENCE_P (decl)); - type = check_elaborated_type_specifier (tag_type, decl, + bool allow_template = (template_parm_lists_apply + || DECL_SELF_REFERENCE_P (decl)); + type = check_elaborated_type_specifier (tag_type, decl, allow_template); if (type == error_mark_node) @@ -15224,15 +15236,16 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, ts = ts_global; template_p = - (parser->num_template_parameter_lists + (template_parm_lists_apply && (cp_parser_next_token_starts_class_definition_p (parser) || cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))); /* An unqualified name was used to reference this type, so there were no qualifying templates. */ - if (!cp_parser_check_template_parameters (parser, - /*num_templates=*/0, - token->location, - /*declarator=*/NULL)) + if (template_parm_lists_apply + && !cp_parser_check_template_parameters (parser, + /*num_templates=*/0, + token->location, + /*declarator=*/NULL)) return error_mark_node; type = xref_tag (tag_type, identifier, ts, template_p); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d88cb7fe506e..d10b03b3924b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-06-26 Adam Butcher + + PR c++/61537 + * g++.dg/template/pr61537.C: New testcase. + 2014-06-25 Bill Schmidt * gfortran.dg/default_format_denormal_2.f90: Remove xfail for diff --git a/gcc/testsuite/g++.dg/template/pr61537.C b/gcc/testsuite/g++.dg/template/pr61537.C new file mode 100644 index 000000000000..12aaf58ef621 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr61537.C @@ -0,0 +1,23 @@ +// PR c++/61537 +// { dg-do compile } + +struct A {}; + +template +struct B +{ + template + void f(U, struct A); +}; + +template +template +void B::f(U, struct A) +{ +} + +int main() +{ + B b; + b.f(42, A()); +}