From patchwork Tue Nov 22 22:40:08 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 127179 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 981041007D2 for ; Wed, 23 Nov 2011 09:40:31 +1100 (EST) Received: (qmail 28080 invoked by alias); 22 Nov 2011 22:40:29 -0000 Received: (qmail 28072 invoked by uid 22791); 22 Nov 2011 22:40:26 -0000 X-SWARE-Spam-Status: No, hits=-6.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 22 Nov 2011 22:40:11 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id pAMMeA7m019108 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 22 Nov 2011 17:40:10 -0500 Received: from localhost (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id pAMMe9vv005665 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 22 Nov 2011 17:40:10 -0500 Received: by localhost (Postfix, from userid 500) id 8F28629C12D; Tue, 22 Nov 2011 23:40:08 +0100 (CET) From: Dodji Seketeli To: Jason Merrill Cc: GCC Patches Subject: Re: [PATCH] PR c++/51145 - Alias template in elaborated-type-specifier References: <4EC6B2DF.6010905@redhat.com> <4ECBAE9B.7030702@redhat.com> X-URL: http://www.redhat.com Date: Tue, 22 Nov 2011 23:40:08 +0100 In-Reply-To: <4ECBAE9B.7030702@redhat.com> (Jason Merrill's message of "Tue, 22 Nov 2011 09:15:55 -0500") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Jason Merrill writes: > On 11/21/2011 11:41 AM, Dodji Seketeli wrote: >> -template class Ptr;//{ dg-error "explicit instantiation|non-class templ|does not decl|anything" } >> +template class Ptr;//{ dg-error "alias templ|specialization|Ptr|after|class" } > > You seem to be using | to mean .* here. Let's choose one key phrase > to check for. :) Actually, I wanted to avoid the verbosity of \[^\n\r\]*, as .* is so greedy that it eats even end of lines. Now I just did bite the bullet and used \[^\n\r\]* instead. > >> -struct A { typedef int X; }; // { dg-error "previous declaration" } >> +struct A { typedef int X; }; > > Let's change dg-error to dg-message instead of dropping the check > entirely on at least one of these tests to avoid a diagnostic quality > regression. OK. I did the change on all the tests. > OK with those changes. Thanks. I am running the test suite again, just in case, with the patch below. I'll commit it tomorrow if it passes. From: Dodji Seketeli Date: Fri, 18 Nov 2011 00:50:21 +0100 Subject: [PATCH] PR c++/51145 - Alias template in elaborated-type-specifier accepted gcc/cp/ PR c++/51145 * decl.c (check_elaborated_type_specifier): Gracefully handle error_mark_node. Accept bound template template parameters. Update diagnostics for alias template specializations. Update comment. * parser.c (cp_parser_elaborated_type_specifier): Use check_elaborated_type_specifier for simple-template-ids as well. gcc/testsuite/ PR c++/51145 * g++.dg/cpp0x/alias-decl-14.C: New test. * g++.dg/cpp0x/alias-decl-2.C: Adjust for tests that were wrongly passing before. * g++.dg/cpp0x/alias-decl-10.C: Likewise and adjust for diagnostic change. * g++.dg/ext/attrib27.C: Adjust for diagnostic change. * g++.dg/lookup/struct1.C: Likewise. * g++.dg/parse/elab1.C: Likewise. * g++.dg/parse/elab2.C: Likewise. * g++.dg/parse/int-as-enum1.C: Likewise. * g++.dg/parse/typedef1.C: Likewise. * g++.dg/parse/typedef3.C: Likewise. * g++.dg/parse/typedef4.C: Likewise. * g++.dg/parse/typedef5.C: Likewise. * g++.dg/template/crash26.C: Likewise. * g++.dg/template/nontype4.C: Likewise. * g++.old-deja/g++.benjamin/typedef01.C: Likewise. * g++.old-deja/g++.brendan/line1.C: Likewise. * g++.old-deja/g++.other/elab1.C: Likewise. * g++.old-deja/g++.other/syntax4.C: Likewise. --- gcc/cp/ChangeLog | 10 ++++++++ gcc/cp/decl.c | 21 ++++++++++++++--- gcc/cp/parser.c | 3 +- gcc/testsuite/ChangeLog | 24 ++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/alias-decl-10.C | 16 ++++++++++--- gcc/testsuite/g++.dg/cpp0x/alias-decl-14.C | 14 +++++++++++ gcc/testsuite/g++.dg/cpp0x/alias-decl-2.C | 2 +- gcc/testsuite/g++.dg/ext/attrib27.C | 2 +- gcc/testsuite/g++.dg/lookup/struct1.C | 4 +- gcc/testsuite/g++.dg/parse/elab1.C | 2 +- gcc/testsuite/g++.dg/parse/elab2.C | 2 +- gcc/testsuite/g++.dg/parse/int-as-enum1.C | 2 +- gcc/testsuite/g++.dg/parse/typedef1.C | 2 +- gcc/testsuite/g++.dg/parse/typedef3.C | 2 +- gcc/testsuite/g++.dg/parse/typedef4.C | 2 +- gcc/testsuite/g++.dg/parse/typedef5.C | 2 +- gcc/testsuite/g++.dg/template/crash26.C | 2 +- gcc/testsuite/g++.dg/template/nontype4.C | 2 +- .../g++.old-deja/g++.benjamin/typedef01.C | 4 +- gcc/testsuite/g++.old-deja/g++.brendan/line1.C | 2 +- gcc/testsuite/g++.old-deja/g++.other/elab1.C | 2 +- gcc/testsuite/g++.old-deja/g++.other/syntax4.C | 2 +- 22 files changed, 97 insertions(+), 27 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-14.C diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b77963b..8406432 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11342,6 +11342,9 @@ check_elaborated_type_specifier (enum tag_types tag_code, { tree type; + if (decl == error_mark_node) + return error_mark_node; + /* In the case of: struct S { struct S *p; }; @@ -11361,10 +11364,15 @@ check_elaborated_type_specifier (enum tag_types tag_code, type, tag_name (tag_code)); return error_mark_node; } + /* Accept bound template template parameters. */ + else if (allow_template_p + && TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM) + ; /* [dcl.type.elab] - If the identifier resolves to a typedef-name or a template - type-parameter, the elaborated-type-specifier is ill-formed. + If the identifier resolves to a typedef-name or the + simple-template-id resolves to an alias template + specialization, the elaborated-type-specifier is ill-formed. In other words, the only legitimate declaration to use in the elaborated type specifier is the implicit typedef created when @@ -11373,8 +11381,13 @@ check_elaborated_type_specifier (enum tag_types tag_code, && !DECL_SELF_REFERENCE_P (decl) && tag_code != typename_type) { - error ("using typedef-name %qD after %qs", decl, tag_name (tag_code)); - error ("%q+D has a previous declaration here", decl); + if (alias_template_specialization_p (type)) + error ("using alias template specialization %qT after %qs", + type, tag_name (tag_code)); + else + error ("using typedef-name %qD after %qs", decl, tag_name (tag_code)); + inform (DECL_SOURCE_LOCATION (decl), + "%qD has a previous declaration here", decl); return error_mark_node; } else if (TREE_CODE (type) != RECORD_TYPE diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d0adaa0..2fdd675 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -13960,7 +13960,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL) type = NULL_TREE; else - type = TREE_TYPE (decl); + type = check_elaborated_type_specifier (tag_type, decl, + /*allow_template_p=*/true); } if (!type) diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-10.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-10.C index 856e429..733e791 100644 --- a/gcc/testsuite/g++.dg/cpp0x/alias-decl-10.C +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-10.C @@ -3,16 +3,24 @@ template using Ptr = T*; Ptr; // { dg-error "does not declare anything" } Ptr; // { dg-error "not a template|does not declare anything" } -template class Ptr;//{ dg-error "explicit instantiation|non-class templ|does not decl|anything" } +template class Ptr;//{ dg-error "alias template specialization\[^\n\r\]*after\[^\n\r\]*class" } template using Arg = T; struct A {}; -template class Arg;// { dg-error "explicit instantiation|non-class templ" } +template class Arg;// { dg-error "alias templ\[^\n\r\]*specialization\[^\n\r\]*Arg\[^\n\r\]*after\[^\n\r\]*class" } template