From patchwork Fri Mar 2 17:36:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 880675 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-474209-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="PkDmGpo5"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3ztGhB0WZ4z9s3Z for ; Sat, 3 Mar 2018 04:36:57 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=OOQ2XU39OnOXlFDNuzQgREHtVcLLsQQ5/F7sOKy2+th8QxZUx+1Zz dX7FsVm6o7oq8ZCV2Zj3R/JrsGAmzzk2IjYng8iaE4ntc+qESWkf9WFOTccmFzKN VgSDenj9lP2WOG9SMCQECGkJSGSSyHzMRGznt4h5bBg6ChBCKdn7go= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=R9PpV6KLPywnGEQyWpQ8frif12A=; b=PkDmGpo5rSB0TRGhrdyf 2dk4aJtuGhAmS0RVD4jy8oLSqNLJLDe+BfPUiqY6SGNijFfYRUp6zv1rLvSyR5h3 RiAe6GWB8bKikEBwW2Vj0oUwI1cnxXZmd4x/nxD9fA181H9EXRNrgO0obNN0bazS BHI7OnnPjxzv/C9HZrR1GNM= Received: (qmail 108554 invoked by alias); 2 Mar 2018 17:36:51 -0000 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 Received: (qmail 108540 invoked by uid 89); 2 Mar 2018 17:36:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=29359 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 02 Mar 2018 17:36:49 +0000 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1B0F12820D for ; Fri, 2 Mar 2018 17:36:48 +0000 (UTC) Received: from redhat.com (unknown [10.40.205.164]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 42BED5D6B2; Fri, 2 Mar 2018 17:36:47 +0000 (UTC) Date: Fri, 2 Mar 2018 18:36:44 +0100 From: Marek Polacek To: Jason Merrill , GCC Patches Subject: C++ PATCH for c++/84578, ICE when initializing flexarr Message-ID: <20180302173644.GK16833@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.9.2 (2017-12-15) We ICE in cxx_eval_vec_init_1 whereby we try to initialize a flexible array member, because the code computing the number of elements of ATYPE wasn't prepared to handle arrays with no bounds. Fixed by using get_array_or_vector_nelts, broken out of existing code. Martin suggested to reject this code, but I decided to leave this as-is for now; we already reject code that actually tries to initialize the flexible array member with some data, e.g.: struct A { constexpr A() : i(), x("foo") {} int i; char x[]; }; A a; Bootstrapped/regtested on x86_64-linux, ok for trunk? 2018-03-02 Marek Polacek PR c++/84578 * constexpr.c (get_array_or_vector_nelts): New. (cxx_eval_array_reference): Use it. (cxx_eval_vec_init_1): Likewise. (cxx_eval_store_expression): Likewise. * g++.dg/ext/flexary29.C: New test. Marek diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c index 39e6cdfb33d..27f841db38f 100644 --- gcc/cp/constexpr.c +++ gcc/cp/constexpr.c @@ -2300,6 +2300,32 @@ diag_array_subscript (const constexpr_ctx *ctx, tree array, tree index) } } +/* Return the number of elements for TYPE (which is an ARRAY_TYPE or + a VECTOR_TYPE). */ + +static tree +get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type, + bool *non_constant_p, bool *overflow_p) +{ + tree nelts; + if (TREE_CODE (type) == ARRAY_TYPE) + { + if (TYPE_DOMAIN (type)) + nelts = array_type_nelts_top (type); + else + nelts = size_zero_node; + } + else if (VECTOR_TYPE_P (type)) + nelts = size_int (TYPE_VECTOR_SUBPARTS (type)); + else + gcc_unreachable (); + + /* For VLAs, the number of elements won't be an integer constant. */ + nelts = cxx_eval_constant_expression (ctx, nelts, false, + non_constant_p, overflow_p); + return nelts; +} + /* Extract element INDEX consisting of CHARS_PER_ELT chars from STRING_CST STRING. */ @@ -2379,22 +2405,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, } } - tree nelts; - if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE) - { - if (TYPE_DOMAIN (TREE_TYPE (ary))) - nelts = array_type_nelts_top (TREE_TYPE (ary)); - else - nelts = size_zero_node; - } - else if (VECTOR_TYPE_P (TREE_TYPE (ary))) - nelts = size_int (TYPE_VECTOR_SUBPARTS (TREE_TYPE (ary))); - else - gcc_unreachable (); - - /* For VLAs, the number of elements won't be an integer constant. */ - nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p, - overflow_p); + tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary), non_constant_p, + overflow_p); VERIFY_CONSTANT (nelts); if ((lval ? !tree_int_cst_le (index, nelts) @@ -2895,7 +2907,6 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, bool *non_constant_p, bool *overflow_p) { tree elttype = TREE_TYPE (atype); - unsigned HOST_WIDE_INT max = tree_to_uhwi (array_type_nelts_top (atype)); verify_ctor_sanity (ctx, atype); vec **p = &CONSTRUCTOR_ELTS (ctx->ctor); bool pre_init = false; @@ -2924,6 +2935,9 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, pre_init = true; } + tree nelts = get_array_or_vector_nelts (ctx, atype, non_constant_p, + overflow_p); + unsigned HOST_WIDE_INT max = tree_to_uhwi (nelts); for (i = 0; i < max; ++i) { tree idx = build_int_cst (size_type_node, i); @@ -3480,19 +3494,8 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, case ARRAY_REF: tree nelts, ary; ary = TREE_OPERAND (probe, 0); - if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE) - { - if (TYPE_DOMAIN (TREE_TYPE (ary))) - nelts = array_type_nelts_top (TREE_TYPE (ary)); - else - nelts = size_zero_node; - } - else if (VECTOR_TYPE_P (TREE_TYPE (ary))) - nelts = size_int (TYPE_VECTOR_SUBPARTS (TREE_TYPE (ary))); - else - gcc_unreachable (); - nelts = cxx_eval_constant_expression (ctx, nelts, false, - non_constant_p, overflow_p); + nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary), + non_constant_p, overflow_p); VERIFY_CONSTANT (nelts); gcc_assert (TREE_CODE (nelts) == INTEGER_CST && TREE_CODE (TREE_OPERAND (probe, 1)) == INTEGER_CST); diff --git gcc/testsuite/g++.dg/ext/flexary29.C gcc/testsuite/g++.dg/ext/flexary29.C index e69de29bb2d..a696fd9804f 100644 --- gcc/testsuite/g++.dg/ext/flexary29.C +++ gcc/testsuite/g++.dg/ext/flexary29.C @@ -0,0 +1,12 @@ +// PR c++/84578 +// { dg-do compile { target c++11 } } +// { dg-options -Wno-pedantic } + +struct A +{ + constexpr A() : i(), x() {} + int i; + char x[]; +}; + +A a;