From patchwork Mon Nov 21 16:41:19 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 126895 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 86E28B71E7 for ; Tue, 22 Nov 2011 05:39:34 +1100 (EST) Received: (qmail 11958 invoked by alias); 21 Nov 2011 18:39:29 -0000 Received: (qmail 11610 invoked by uid 22791); 21 Nov 2011 18:39:23 -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; Mon, 21 Nov 2011 18:38:42 +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 pALIcLBG020904 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 21 Nov 2011 13:38:42 -0500 Received: from localhost (ovpn-116-17.ams2.redhat.com [10.36.116.17]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id pALGfL4O025328 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 21 Nov 2011 11:41:22 -0500 Received: by localhost (Postfix, from userid 500) id 293CF29C12D; Mon, 21 Nov 2011 17:41:20 +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> X-URL: http://www.redhat.com Date: Mon, 21 Nov 2011 17:41:19 +0100 In-Reply-To: <4EC6B2DF.6010905@redhat.com> (Jason Merrill's message of "Fri, 18 Nov 2011 14:32:47 -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: > See my comment in the PR. Yes, sorry I have missed it. Here is an updated patch hopefully addressing that comment. I have also updated a bunch of tests as a result of the change from error to note. Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk. 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/decl.c | 21 ++++++++++++++++--- gcc/cp/parser.c | 3 +- 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 +- 20 files changed, 63 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 f839112..08b9c13 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -13933,7 +13933,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..6adb785 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 templ|specialization|Ptr|after|class" } template using Arg = T; struct A {}; -template class Arg;// { dg-error "explicit instantiation|non-class templ" } +template class Arg;// { dg-error "alias templ|specialization|Arg|after|class" } template