From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11856 invoked by alias); 25 Jun 2014 20:05:10 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 11838 invoked by uid 89); 25 Jun 2014 20:05:10 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL,BAYES_00,DATE_IN_PAST_12_24,FREEMAIL_FROM,KAM_COUK,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=no version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mail-we0-f179.google.com Received: from mail-we0-f179.google.com (HELO mail-we0-f179.google.com) (74.125.82.179) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Wed, 25 Jun 2014 20:05:09 +0000 Received: by mail-we0-f179.google.com with SMTP id w62so2505064wes.24 for ; Wed, 25 Jun 2014 13:05:02 -0700 (PDT) X-Received: by 10.194.186.178 with SMTP id fl18mr11931826wjc.83.1403726701641; Wed, 25 Jun 2014 13:05:01 -0700 (PDT) Received: from xtorus.lan (munkyhouse.force9.co.uk. [84.92.244.81]) by mx.google.com with ESMTPSA id ey16sm57237689wid.14.2014.06.25.13.04.57 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 25 Jun 2014 13:04:59 -0700 (PDT) From: Adam Butcher To: Jason Merrill , Paolo Carlini Cc: gcc-patches@gcc.gnu.org, Alexander Adam , Jonathan Wakely , Adam Butcher Subject: Re: [PATCH] Fix PR c++/61537 Date: Wed, 25 Jun 2014 20:05:00 -0000 Message-Id: <1403666183-13009-1-git-send-email-adam@jessamine.co.uk> In-Reply-To: <53AAC4B2.3040905@redhat.com> References: <53AAC4B2.3040905@redhat.com> X-SW-Source: 2014-06/txt/msg02053.txt.bz2 * parser.c (cp_parser_elaborated_type_specifier): Only consider template parameter lists outside of function parameter scope. * g++.dg/template/pr61537.C: New testcase. --- gcc/cp/parser.c | 31 ++++++++++++++++++++++--------- gcc/testsuite/g++.dg/template/pr61537.C | 23 +++++++++++++++++++++++ 2 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/pr61537.C 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/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 +struct B +{ + template + void f(U, struct A); +}; + +template +template +void B::f(U, struct A) +{ +} + +int main() +{ + B b; + b.f(42, A()); +} -- 2.0.0