From patchwork Tue Dec 11 18:16:19 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 205280 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 5DBCA2C007B for ; Wed, 12 Dec 2012 05:16:36 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1355854596; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:Subject: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=NMVMDFo qDBWnI71GL7XEjqzbQUQ=; b=FFRFl68WSB2KgMxzUuGTQMp76HHaJTuXKQD3CNN 2ULsJSOC/igAutKP9MM8iXGEvTDhYIjhB5FvCWJXSsymmEA6g0TeMX1V38O5S9Fi D2rBT2HsXcA6bOpJZqk4rRTyYtxusblaO79qUdgZGmpeOcB2Shu7LytJnb0LtVbL hUa4= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=fuweikifp996O740j6vn/SyiZmh2jADVWOidO1jzqd1K/pUgC3tFd+lAiMNRei MBO6EfH0bL1hBbdUdUiislJmeJuWvKaERft3aA2sqrSFPT64DLMZ9aI4CKqxbo7p DKEmbl2RJONQa4XQiijqGxAEsZIdIJcagO1tDQAJYchOo=; Received: (qmail 4738 invoked by alias); 11 Dec 2012 18:16:30 -0000 Received: (qmail 4728 invoked by uid 22791); 11 Dec 2012 18:16:29 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, 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, 11 Dec 2012 18:16:21 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qBBIGKkr018756 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 11 Dec 2012 13:16:21 -0500 Received: from [10.3.113.19] ([10.3.113.19]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id qBBIGKKV003855 for ; Tue, 11 Dec 2012 13:16:20 -0500 Message-ID: <50C77873.8090808@redhat.com> Date: Tue, 11 Dec 2012 13:16:19 -0500 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/54416 (ICE after error on bogus specialization) 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 In this testcase we get confused by a specialization nested inside a class template; the members of the specialization end up having dependent template arguments, and then we get confused when we try to define one of them in a context that has no template headers. Fixed by rejecting the definition of the specialization, and therefore the definition of the member of the specialization. Tested x86_64-pc-linux-gnu, applying to trunk. commit 9bcbafc418c3f7aff48c8e98f362e7f44849051e Author: Jason Merrill Date: Tue Dec 11 10:59:36 2012 -0500 * pt.c (maybe_process_partial_specialization): Handle aliases first. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 1bc9e1b..f30a1e1 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -812,13 +812,17 @@ maybe_process_partial_specialization (tree type) context = TYPE_CONTEXT (type); - if ((CLASS_TYPE_P (type) && CLASSTYPE_USE_TEMPLATE (type)) - /* Consider non-class instantiations of alias templates as - well. */ - || (TYPE_P (type) - && TYPE_TEMPLATE_INFO (type) - && DECL_LANG_SPECIFIC (TYPE_NAME (type)) - && DECL_USE_TEMPLATE (TYPE_NAME (type)))) + if (TYPE_ALIAS_P (type)) + { + if (TYPE_TEMPLATE_INFO (type) + && DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (type))) + error ("specialization of alias template %qD", + TYPE_TI_TEMPLATE (type)); + else + error ("explicit specialization of non-template %qT", type); + return error_mark_node; + } + else if (CLASS_TYPE_P (type) && CLASSTYPE_USE_TEMPLATE (type)) { /* This is for ordinary explicit specialization and partial specialization of a template class such as: @@ -831,8 +835,7 @@ maybe_process_partial_specialization (tree type) Make sure that `C' and `C' are implicit instantiations. */ - if (CLASS_TYPE_P (type) - && CLASSTYPE_IMPLICIT_INSTANTIATION (type) + if (CLASSTYPE_IMPLICIT_INSTANTIATION (type) && !COMPLETE_TYPE_P (type)) { check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (type)); @@ -845,16 +848,9 @@ maybe_process_partial_specialization (tree type) return error_mark_node; } } - else if (CLASS_TYPE_P (type) - && CLASSTYPE_TEMPLATE_INSTANTIATION (type)) + else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)) error ("specialization of %qT after instantiation", type); - if (DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (type))) - { - error ("partial specialization of alias template %qD", - TYPE_TI_TEMPLATE (type)); - return error_mark_node; - } } else if (CLASS_TYPE_P (type) && !CLASSTYPE_USE_TEMPLATE (type) diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-1.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-1.C index d0eda5f..cbba90f 100644 --- a/gcc/testsuite/g++.dg/cpp0x/alias-decl-1.C +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-1.C @@ -5,10 +5,10 @@ template struct A0 {}; template using AA0 = A0; -template struct AA0 {}; // { dg-error "partial specialization" } +template struct AA0 {}; // { dg-error "specialization" } template using Ptr = U*; -template struct Ptr {}; // { dg-error "partial specialization" } +template struct Ptr {}; // { dg-error "specialization" } struct A { using A = int;//{ dg-error "nested|has|same name as|class|in which|declared" } commit e575667938e576ceeede4bdb00361d2b52540a48 Author: Jason Merrill Date: Sat Dec 8 20:16:30 2012 -0500 PR c++/54416 * pt.c (maybe_process_partial_specialization): Don't accept definition of a specialization without the appropriate header. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f30a1e1..91450d8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -850,7 +850,13 @@ maybe_process_partial_specialization (tree type) } else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)) error ("specialization of %qT after instantiation", type); - + else if (errorcount && !processing_specialization + && CLASSTYPE_TEMPLATE_SPECIALIZATION (type) + && !uses_template_parms (CLASSTYPE_TI_ARGS (type))) + /* Trying to define a specialization either without a template<> header + or in an inappropriate place. We've already given an error, so just + bail now so we don't actually define the specialization. */ + return error_mark_node; } else if (CLASS_TYPE_P (type) && !CLASSTYPE_USE_TEMPLATE (type) diff --git a/gcc/testsuite/g++.dg/template/crash105.C b/gcc/testsuite/g++.dg/template/crash105.C index 649bf8b..8cfff6a 100644 --- a/gcc/testsuite/g++.dg/template/crash105.C +++ b/gcc/testsuite/g++.dg/template/crash105.C @@ -10,5 +10,8 @@ template < typename > struct S < int > void f () { - S < int >::f (); // { dg-error "cannot call" } + S < int >::f (); } + +// Don't be picky about error-recovery. +// { dg-prune-output "." } diff --git a/gcc/testsuite/g++.dg/template/error48.C b/gcc/testsuite/g++.dg/template/error48.C new file mode 100644 index 0000000..483f7b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error48.C @@ -0,0 +1,15 @@ +// PR c++/54416 + +template < typename T > struct foo; +template <> struct foo < int >; +template < typename T > struct bar +{ + template <> struct foo < int > // { dg-error "non-namespace scope" } + { + void baz (); + }; +}; +void foo < int >::baz () { } + +// Don't be picky about error-recovery. +// { dg-prune-output "." }