From patchwork Sat Aug 6 04:28:24 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 108756 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 519CAB6F77 for ; Sat, 6 Aug 2011 14:28:45 +1000 (EST) Received: (qmail 30620 invoked by alias); 6 Aug 2011 04:28:42 -0000 Received: (qmail 30611 invoked by uid 22791); 6 Aug 2011 04:28:41 -0000 X-SWARE-Spam-Status: No, hits=-6.9 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; Sat, 06 Aug 2011 04:28:26 +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.14.4/8.14.4) with ESMTP id p764SQp7029593 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sat, 6 Aug 2011 00:28:26 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p764SPgm014005 for ; Sat, 6 Aug 2011 00:28:25 -0400 Received: from [0.0.0.0] (ovpn-113-87.phx2.redhat.com [10.3.113.87]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p764SO57024640 for ; Sat, 6 Aug 2011 00:28:25 -0400 Message-ID: <4E3CC2E8.2070004@redhat.com> Date: Sat, 06 Aug 2011 00:28:24 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:5.0) Gecko/20110719 Thunderbird/5.0 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/49988 (constexpr causing wrong code) 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 constexpr on the A constructor led us to try to expand the call in the B constructor to a constant. But in that call we're passing the B parameter s, which is not constant, so it should just fail quietly. But instead we were trying to treat it as a STRING_CST, which causes an ICE with checking enabled, or wrong code with checking off. Tested x86_64-pc-linux-gnu, applying to trunk and 4.6. On the 4.6 branch I replaced the gcc_unreachable with just returning t to be extra conservative. commit 15dfe0b93a072a167d7a818799487119f516231d Author: Jason Merrill Date: Fri Aug 5 16:12:24 2011 -0400 PR c++/49988 * semantics.c (cxx_eval_array_reference): Handle failure to reduce the array operand to something we can work with. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index ac24b77..2f02e69 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -6428,12 +6428,19 @@ cxx_eval_array_reference (const constexpr_call *call, tree t, elem_type = TREE_TYPE (TREE_TYPE (ary)); if (TREE_CODE (ary) == CONSTRUCTOR) len = CONSTRUCTOR_NELTS (ary); - else + else if (TREE_CODE (ary) == STRING_CST) { elem_nchars = (TYPE_PRECISION (elem_type) / TYPE_PRECISION (char_type_node)); len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars; } + else + { + /* We can't do anything with other tree codes, so use + VERIFY_CONSTANT to complain and fail. */ + VERIFY_CONSTANT (ary); + gcc_unreachable (); + } if (compare_tree_int (index, len) >= 0) { if (tree_int_cst_lt (index, array_type_nelts_top (TREE_TYPE (ary)))) diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-non-const-arg3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-non-const-arg3.C new file mode 100644 index 0000000..581be6d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-non-const-arg3.C @@ -0,0 +1,23 @@ +// PR c++/49988 +// { dg-options -std=c++0x } +// { dg-do run } + +template struct X { }; + +struct A { + char data[3]; + template + constexpr + A(const char (&s)[3], X x) : data{ s[I]...} { } +}; +struct B { + A a; + B(const char (&s)[3]) : a{s,X<0,1,2>{}} { } +}; + +int main() +{ + B b{"12"}; + if (b.a.data[0] != '1') + return 1; +}