From patchwork Fri May 6 21:52:04 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 94438 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 202E1B6F44 for ; Sat, 7 May 2011 07:52:24 +1000 (EST) Received: (qmail 7791 invoked by alias); 6 May 2011 21:52:23 -0000 Received: (qmail 7783 invoked by uid 22791); 6 May 2011 21:52:23 -0000 X-SWARE-Spam-Status: No, hits=-6.3 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; Fri, 06 May 2011 21:52:05 +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 p46Lq4DT014397 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 6 May 2011 17:52:05 -0400 Received: from [127.0.0.1] (ovpn-113-126.phx2.redhat.com [10.3.113.126]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p46Lq49m002675 for ; Fri, 6 May 2011 17:52:04 -0400 Message-ID: <4DC46D84.2090906@redhat.com> Date: Fri, 06 May 2011 17:52:04 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.15) Gecko/20110421 Fedora/3.1.9-2.fc14 Lightning/1.0b2 Thunderbird/3.1.9 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/48911 (constexpr and implicit aggregate initializers) 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 48911, the constexpr expander wasn't properly dealing with aggregate/string constant array initializers with omitted elements. We should build up a value-initialization as needed. Tested x86_64-pc-linux-gnu, applying to trunk and 4.6. commit b557b9384f1a6509735c25574f1c1d09703e6252 Author: Jason Merrill Date: Fri May 6 10:21:38 2011 -0400 PR c++/48911 * semantics.c (cxx_eval_array_reference): Handle implicit initializers. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 8bf5a52..d0c559b 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -6324,6 +6324,7 @@ cxx_eval_array_reference (const constexpr_call *call, tree t, non_constant_p); tree index, oldidx; HOST_WIDE_INT i; + tree elem_type; unsigned len, elem_nchars = 1; if (*non_constant_p) return t; @@ -6336,16 +6337,27 @@ cxx_eval_array_reference (const constexpr_call *call, tree t, return t; else if (addr) return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL); + elem_type = TREE_TYPE (TREE_TYPE (ary)); if (TREE_CODE (ary) == CONSTRUCTOR) len = CONSTRUCTOR_NELTS (ary); else { - elem_nchars = (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (ary))) + elem_nchars = (TYPE_PRECISION (elem_type) / TYPE_PRECISION (char_type_node)); len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars; } if (compare_tree_int (index, len) >= 0) { + if (tree_int_cst_lt (index, array_type_nelts_top (TREE_TYPE (ary)))) + { + /* If it's within the array bounds but doesn't have an explicit + initializer, it's value-initialized. */ + tree val = build_value_init (elem_type, tf_warning_or_error); + return cxx_eval_constant_expression (call, val, + allow_non_constant, addr, + non_constant_p); + } + if (!allow_non_constant) error ("array subscript out of bound"); *non_constant_p = true; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-missing.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-missing.C new file mode 100644 index 0000000..547f552 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-missing.C @@ -0,0 +1,39 @@ +// PR c++/48911 +// { dg-do compile } +// { dg-options "-std=c++0x" } + +#define SA(X) static_assert((X),#X) + +struct A +{ + constexpr A () : a (6) {} + int a; +}; + +int +main () +{ + constexpr int a[2] = { 42 }; + constexpr int i = a[1]; + SA(i==0); + constexpr int b[1] = { }; + constexpr int j = b[0]; + SA(j==0); + constexpr char c[2] = "a"; + constexpr char k = c[1]; + SA(k==0); + constexpr char d[2] = ""; + constexpr char l = d[1]; + SA(l==0); + constexpr wchar_t e[2] = L"a"; + constexpr wchar_t m = e[1]; + SA(m==0); + constexpr wchar_t f[2] = L""; + constexpr wchar_t n = f[1]; + SA(n==0); + constexpr A g[2] = { A () }; + constexpr A o = g[0]; + SA(o.a == 6); + constexpr A p = g[1]; + SA(p.a == 6); +}