diff options
author | Adam Butcher <adam@jessamine.co.uk> | 2014-06-26 06:12:52 +0100 |
---|---|---|
committer | Adam Butcher <abutcher@gcc.gnu.org> | 2014-06-26 06:12:52 +0100 |
commit | 2626fc495bb50774416896f898914977a5071d29 (patch) | |
tree | d6a20d454077d68e7f6edbdfae331e152a9a9cad /gcc | |
parent | b9b5f43367ced552bdd92808fa3a38cb55cb2fd3 (diff) | |
download | gcc-2626fc495bb50774416896f898914977a5071d29.zip gcc-2626fc495bb50774416896f898914977a5071d29.tar.gz gcc-2626fc495bb50774416896f898914977a5071d29.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/parser.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/pr61537.C | 23 |
4 files changed, 56 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c3d520e..124f4d6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2014-06-26 Adam Butcher <adam@jessamine.co.uk> + + 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 <paolo.carlini@oracle.com> DR 178 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 41200a0..c440c99 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 d88cb7f..d10b03b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-06-26 Adam Butcher <adam@jessamine.co.uk> + + PR c++/61537 + * g++.dg/template/pr61537.C: New testcase. + 2014-06-25 Bill Schmidt <wschmidt@linux.vnet.ibm.com> * 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 0000000..12aaf58 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr61537.C @@ -0,0 +1,23 @@ +// PR c++/61537 +// { dg-do compile } + +struct A {}; + +template <typename T> +struct B +{ + template <typename U> + void f(U, struct A); +}; + +template <typename T> +template <typename U> +void B<T>::f(U, struct A) +{ +} + +int main() +{ + B<char> b; + b.f(42, A()); +} |