From patchwork Thu Nov 4 02:02:22 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 70092 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 90D221007D2 for ; Thu, 4 Nov 2010 13:02:35 +1100 (EST) Received: (qmail 21178 invoked by alias); 4 Nov 2010 02:02:31 -0000 Received: (qmail 21015 invoked by uid 22791); 4 Nov 2010 02:02:30 -0000 X-SWARE-Spam-Status: No, hits=-6.1 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, 04 Nov 2010 02:02:25 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oA422NOp005003 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 3 Nov 2010 22:02:24 -0400 Received: from [127.0.0.1] ([10.3.113.16]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id oA422NMc001174 for ; Wed, 3 Nov 2010 22:02:23 -0400 Message-ID: <4CD2142E.7000102@redhat.com> Date: Wed, 03 Nov 2010 22:02:22 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.15) Gecko/20101031 Lightning/1.0b1 Shredder/3.0.11pre MIME-Version: 1.0 To: gcc-patches List Subject: Re: C++ PATCH for c++/46289 (ICE on invalid mem-init-list in constexpr ctor) References: <4CD1B18A.6070000@redhat.com> In-Reply-To: <4CD1B18A.6070000@redhat.com> 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 On 11/03/2010 03:01 PM, Jason Merrill wrote: > The testcase in the PR ought to be valid, but even on an invalid > initializer we shouldn't ICE. This patch just fixes the ICE. And this patch fixes the error. Tested x86_64-pc-linux-gnu, applied to trunk. commit 806ad75a68d2a2ecede77d1857cc1404d395e6a6 Author: Jason Merrill Date: Wed Nov 3 18:28:18 2010 -0400 PR c++/46289 * call.c (can_convert_array): New fn. (build_aggr_conv): Use it. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index a1c8682..4507f3d 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -639,6 +639,29 @@ build_list_conv (tree type, tree ctor, int flags) return t; } +/* Subroutine of build_aggr_conv: check whether CTOR, a braced-init-list, + is a valid aggregate initializer for array type ATYPE. */ + +static bool +can_convert_array (tree atype, tree ctor, int flags) +{ + unsigned i; + tree elttype = TREE_TYPE (atype); + for (i = 0; i < CONSTRUCTOR_NELTS (ctor); ++i) + { + tree val = CONSTRUCTOR_ELT (ctor, i)->value; + bool ok; + if (TREE_CODE (elttype) == ARRAY_TYPE + && TREE_CODE (val) == CONSTRUCTOR) + ok = can_convert_array (elttype, val, flags); + else + ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags); + if (!ok) + return false; + } + return true; +} + /* Represent a conversion from CTOR, a braced-init-list, to TYPE, an aggregate class, if such a conversion is possible. */ @@ -652,24 +675,31 @@ build_aggr_conv (tree type, tree ctor, int flags) for (; field; field = next_initializable_field (DECL_CHAIN (field))) { + tree ftype = TREE_TYPE (field); + tree val; + bool ok; + if (i < CONSTRUCTOR_NELTS (ctor)) - { - constructor_elt *ce = CONSTRUCTOR_ELT (ctor, i); - if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (ce->value), - ce->value, flags)) - return NULL; - ++i; - if (TREE_CODE (type) == UNION_TYPE) - break; - } + val = CONSTRUCTOR_ELT (ctor, i)->value; else { if (empty_ctor == NULL_TREE) empty_ctor = build_constructor (init_list_type_node, NULL); - if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (empty_ctor), - empty_ctor, flags)) - return NULL; + val = empty_ctor; } + ++i; + + if (TREE_CODE (ftype) == ARRAY_TYPE + && TREE_CODE (val) == CONSTRUCTOR) + ok = can_convert_array (ftype, val, flags); + else + ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags); + + if (!ok) + return NULL; + + if (TREE_CODE (type) == UNION_TYPE) + break; } if (i < CONSTRUCTOR_NELTS (ctor)) diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist45.C b/gcc/testsuite/g++.dg/cpp0x/initlist45.C new file mode 100644 index 0000000..0e34bc1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist45.C @@ -0,0 +1,13 @@ +// PR c++/46289 +// { dg-options -std=c++0x } + +struct A +{ + int i[2]; +}; + +struct B +{ + A a; + B(): a({{1,2}}) { } +};