From patchwork Mon Sep 13 19:54:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 44961 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 31FF63858015 for ; Mon, 13 Sep 2021 19:55:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 31FF63858015 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1631562929; bh=BnygBPPnBUujvLunhFlMxJnH7xgnzw3Xk5QC+pWkSPI=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=XuvoFd9gzhC4JSQBHDUHLgD1jhQVSe72GwEBU2FZ3TpHxV1lNzn3Zr0l7QcSVeuXw P8OyWDDJwyfhsw2N7/KMLvxPxE1i3TbJZLve/FdQh0LU6WRzDOBZdEPUkQ5y2DN1AH 8Pkb9zYLDQqs4uaQCtKnuxd6tusOIcZzi+x0Be/Y= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id 053873858402 for ; Mon, 13 Sep 2021 19:54:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 053873858402 Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-247-QBxmq2Z0NoWjGc7YlJio_w-1; Mon, 13 Sep 2021 15:54:58 -0400 X-MC-Unique: QBxmq2Z0NoWjGc7YlJio_w-1 Received: by mail-qv1-f70.google.com with SMTP id z6-20020a056214060600b0037a3f6bd9abso57074652qvw.3 for ; Mon, 13 Sep 2021 12:54:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=BnygBPPnBUujvLunhFlMxJnH7xgnzw3Xk5QC+pWkSPI=; b=f5DgB74ghaRJg6NX++v9TdIfg1FpHF8l0oQoZEcrfnlfVyOH1RX+XayKhrhuOXIrdL kQ63OQXN8AJ+IVjdRcz6jnlCYtdmX6uQeFPUn/LqELO/4B65S0+UzgQd/9PdaQ9CYUe0 Ea86cu+meCTbyu6pFIMza37SEdzguhCyeWJBI27fY0p/Rdl+DTmffpnyk9AqjHGsVfTd R9zcsuhj2dc6G/vP+kyVCOgBkbLQeKV2GcwOZuLjYCgIhRueWy7n035okQ+wG56UnjTZ 6zy9/9YF7/NqEg2yLnt7KlBu863e9T5c9xel5mCHaeqmX56bIN+ta9XcmEqg0TWI0FzU C6vg== X-Gm-Message-State: AOAM530b1NAIR1sfxFNQbsnLv5r2i1WNXhf2RHqMApvwhhOuAbV+XHRN mxyc35OJDQ2xB2/E30VNetaHpNuCrsQZIXXcGtLSVejYugMjyKjq5yUD99RGAvC2wWbarXbuU12 6HbVrwc645goFmJIl63R8l2bRdYbsKKNt+2RO4G/Ir6ydUKrDYfYYqRHO45tH7X1QAqE= X-Received: by 2002:a05:620a:2f1:: with SMTP id a17mr1379252qko.122.1631562898112; Mon, 13 Sep 2021 12:54:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz8WCa0cTkg2fv73RQuNqgsj+q8Qwnrw9Vxm8dj7mSrwwN9QzBO0DpwhZnv33+mLdh7FlMvFg== X-Received: by 2002:a05:620a:2f1:: with SMTP id a17mr1379233qko.122.1631562897773; Mon, 13 Sep 2021 12:54:57 -0700 (PDT) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id d12sm5955784qka.60.2021.09.13.12.54.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Sep 2021 12:54:56 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH] c++: empty union member activation during constexpr [PR102163] Date: Mon, 13 Sep 2021 15:54:54 -0400 Message-Id: <20210913195454.3679513-1-ppalka@redhat.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-16.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Here, the union's constructor is defined to activate its empty data member _M_rest, but during constexpr evaluation of this constructor the subobject constructor call to O::O(&_M_rest, 42) produces no side effects that actually activates the member, so the union still appears uninitialized after the fact. This patch fixes this by faking up a dummy MODIFY_EXPR in this situation, whose evaluation ensures the member gets activated. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk? PR c++/102163 gcc/cp/ChangeLog: * constexpr.c (cxx_eval_call_expression): After evaluating a constructor call for an empty union member, produce a side effect that makes sure the member is activated. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-empty17.C: New test. --- gcc/cp/constexpr.c | 34 +++++++++++++++---- .../g++.dg/cpp0x/constexpr-empty17.C | 21 ++++++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-empty17.C diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 7772fe62d95..40b0b80b438 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2787,12 +2787,34 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, &jump_target); if (DECL_CONSTRUCTOR_P (fun)) - /* This can be null for a subobject constructor call, in - which case what we care about is the initialization - side-effects rather than the value. We could get at the - value by evaluating *this, but we don't bother; there's - no need to put such a call in the hash table. */ - result = lval ? ctx->object : ctx->ctor; + { + /* This can be null for a subobject constructor call, in + which case what we care about is the initialization + side-effects rather than the value. We could get at the + value by evaluating *this, but we don't bother; there's + no need to put such a call in the hash table. */ + result = lval ? ctx->object : ctx->ctor; + + if (!result && new_obj + && TREE_CODE (new_obj) == COMPONENT_REF + && TREE_CODE (TREE_TYPE + (TREE_OPERAND (new_obj, 0))) == UNION_TYPE + && is_really_empty_class (TREE_TYPE (new_obj), + /*ignore_vptr*/false)) + { + /* This constructor call for an empty union member might not + have produced a side effect that actually activated the + member. So produce such a side effect now to ensure the + union appears initialized. */ + tree activate = build2 (MODIFY_EXPR, TREE_TYPE (new_obj), + new_obj, + build_constructor (TREE_TYPE (new_obj), + NULL)); + cxx_eval_constant_expression (ctx, activate, lval, + non_constant_p, overflow_p); + ggc_free (activate); + } + } else if (VOID_TYPE_P (TREE_TYPE (res))) result = void_node; else diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-empty17.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty17.C new file mode 100644 index 00000000000..9d753a3bb69 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty17.C @@ -0,0 +1,21 @@ +// PR c++/102163 +// { dg-do compile { target c++11 } } + +struct O { + constexpr O(int) { } +}; + +union _Variadic_union { + constexpr _Variadic_union(int __arg) : _M_rest(__arg) { } + + int _M_first; + O _M_rest; +}; + + +struct _Variant_storage { + constexpr _Variant_storage() : _M_u(42) {} + _Variadic_union _M_u; +}; + +constexpr _Variant_storage w;