From patchwork Thu Aug 19 16:54:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 62202 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 A612BB70EB for ; Fri, 20 Aug 2010 02:54:31 +1000 (EST) Received: (qmail 5692 invoked by alias); 19 Aug 2010 16:54:30 -0000 Received: (qmail 5682 invoked by uid 22791); 19 Aug 2010 16:54:29 -0000 X-SWARE-Spam-Status: No, hits=-6.0 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD 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; Thu, 19 Aug 2010 16:54:24 +0000 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o7JGsNPe029308 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 19 Aug 2010 12:54:23 -0400 Received: from [IPv6:::1] (ovpn-113-45.phx2.redhat.com [10.3.113.45]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o7JGsMLA008368 for ; Thu, 19 Aug 2010 12:54:22 -0400 Message-ID: <4C6D61BD.9030006@redhat.com> Date: Thu, 19 Aug 2010 12:54:21 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.11) Gecko/20100814 Lightning/1.0b1 Shredder/3.0.7pre MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/45315 (ICE on new T()) 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 The hoops that we jump through to implement value-initialization of aggregates don't work in templates, so we shouldn't try to do it at all; we're just going to throw away the result of build_new_1 anyway. Tested x86_64-pc-linux-gnu, applied to trunk. commit 2bec61b98748c07fe7e985d787cf92b9a7faa4e5 Author: Jason Merrill Date: Wed Aug 18 16:00:41 2010 -0400 PR c++/45315 * init.c (build_new_1): Don't use build_value_init in a template. (build_value_init): Make sure we don't. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 8555fad..189bcbe 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -295,6 +295,9 @@ build_value_init (tree type, tsubst_flags_t complain) zero-initializing the object and then calling the default constructor. */ + /* The AGGR_INIT_EXPR tweaking below breaks in templates. */ + gcc_assert (!processing_template_decl); + if (CLASS_TYPE_P (type)) { if (type_has_user_provided_constructor (type)) @@ -2310,7 +2313,8 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, { init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain); - if (TYPE_NEEDS_CONSTRUCTING (type) && !explicit_value_init_p) + if (TYPE_NEEDS_CONSTRUCTING (type) + && (!explicit_value_init_p || processing_template_decl)) { init_expr = build_special_member_call (init_expr, complete_ctor_identifier, @@ -2320,11 +2324,17 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, } else if (explicit_value_init_p) { - /* Something like `new int()'. */ - tree val = build_value_init (type, complain); - if (val == error_mark_node) - return error_mark_node; - init_expr = build2 (INIT_EXPR, type, init_expr, val); + if (processing_template_decl) + /* Don't worry about it, we'll handle this properly at + instantiation time. */; + else + { + /* Something like `new int()'. */ + tree val = build_value_init (type, complain); + if (val == error_mark_node) + return error_mark_node; + init_expr = build2 (INIT_EXPR, type, init_expr, val); + } } else { diff --git a/gcc/testsuite/g++.dg/init/value8.C b/gcc/testsuite/g++.dg/init/value8.C new file mode 100644 index 0000000..0a9b90b --- /dev/null +++ b/gcc/testsuite/g++.dg/init/value8.C @@ -0,0 +1,19 @@ +// PR c++/45315 + +struct A +{ + A (); +}; + +template < int > struct B : A +{ + void foo () + { + new B < 0 > (); + } +}; + +int main() +{ + B<1>().foo(); +}