From patchwork Wed Jul 27 09:09:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 202 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6a10:b5d6:b0:2b9:3548:2db5 with SMTP id v22csp272168pxt; Wed, 27 Jul 2022 02:10:28 -0700 (PDT) X-Google-Smtp-Source: AGRyM1u4CSxDfWBr8pKouXxYnQWVrOO1mX93oaXT24ixb/J0OWCNAXrRAIIc+zHuGHNgSsCIcFWo X-Received: by 2002:a05:6402:3511:b0:43b:c84c:e233 with SMTP id b17-20020a056402351100b0043bc84ce233mr22030156edd.211.1658913028463; Wed, 27 Jul 2022 02:10:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658913028; cv=none; d=google.com; s=arc-20160816; b=nB1E1jh78b0OXC0B6kGGJxYeyQ9KnD0mAOtBSViH5HYlDL1elYU31LvLu5ZfgT5MDI CbNgNHkYtL8CryVU7xonyDhzK8Ro+UqQo7uh7FagpKBDDwSUoy24oHSfEpYvG69xEAjv N6DNGrZfS1igpakS0X/ROMXUCnYb2RavJVeXJcLbSHPqNymZRWGscLFkGDsdY+P3BVc3 8kVrtlfB2pCrNnF2CbnsCpY2rhjofVigeNNSAyLECRtl2oLxh0cXwzb0zMsd4wePxRzN lvfpjBZ2N366+e8caimXeC+l/u27OVTynKtjVprAXktQAcMNMxfgrESlXObQT+RXBpyA jtiQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :content-disposition:in-reply-to:mime-version:references:message-id :subject:to:date:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=2ggInge6gWIK5Km3rOgzdFFPMbVe96eFjvl2xVqOT7s=; b=jQfR26Dm7oSv1Aap1OZvA5oM4Yi5cApw3EOporQ+3zCreUtAUehqJ1KTqdn3VINjoD BxjQpvSjT7LCbZm3l01sum4+BQM7e/+d0mN6niPZ+m3NJuciHUQMph8Jp/U4Oshbw87E EmkXsiBalR/j+eiNr4IH/MccJAZgIHUM7BJRhWW3m2LWvVQj4kj8DQVSsrW/aAl2/czT y7kESo4ESn0onmIUjdlmANrGu3Rf8/RCW0migxZbj9jb7F+o1s5pA/UivKyymLUuS5cX Yq6qmzmnVVCYIYZfoo6bes8WZGzbx8U58OcgP9PS+/EaxtuJHwJYt4PGA2VeJKcOS1pt ABZA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=Xtrd4aKS; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id e15-20020a056402190f00b0043bb87a322csi21962343edz.52.2022.07.27.02.10.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Jul 2022 02:10:28 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=Xtrd4aKS; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 19C323857001 for ; Wed, 27 Jul 2022 09:10:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 19C323857001 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1658913027; bh=2ggInge6gWIK5Km3rOgzdFFPMbVe96eFjvl2xVqOT7s=; h=Date:To:Subject:References:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Xtrd4aKSZwYlTOYJf0F7fPiUQH0OZCEFUUNkEIxnpdQPJFMVOXsdzLKnnPHDY8hlg 3YhEeDa5jRLWvnogwhh0qMRB15r5bcrr/4Z1aofu0VBNoz5A7rBxJZWSQyLM+k1eSW zAVhDZJpgN0391a1UjcyZJqnVtoPhIgeY6LRzfpk= 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 [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 2B5833857374 for ; Wed, 27 Jul 2022 09:09:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2B5833857374 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-30-x42WKh54PIWhsEGGdaBqzQ-1; Wed, 27 Jul 2022 05:09:24 -0400 X-MC-Unique: x42WKh54PIWhsEGGdaBqzQ-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5FCF7280EE24 for ; Wed, 27 Jul 2022 09:09:24 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.41]) by smtp.corp.redhat.com (Postfix) with ESMTPS id EBC671121314; Wed, 27 Jul 2022 09:09:23 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 26R99LjS2208094 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Wed, 27 Jul 2022 11:09:21 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 26R99GrU2208093; Wed, 27 Jul 2022 11:09:16 +0200 Date: Wed, 27 Jul 2022 11:09:15 +0200 To: Jason Merrill Subject: [PATCH] c++, v4: Add support for __real__/__imag__ modifications in constant expressions [PR88174] Message-ID: References: <4d9319d5-1890-7c99-6c1b-d940f873a590@redhat.com> <38ccc92a-6772-75d9-1ac9-fc3252734291@redhat.com> MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Cc: gcc-patches@gcc.gnu.org Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1739496387808679060?= X-GMAIL-MSGID: =?utf-8?q?1739496387808679060?= On Tue, Jul 05, 2022 at 04:44:41PM -0400, Jason Merrill wrote: > But preeval should always be true, so we'd never reach the new handling in > the if (!preeval) block. Certainly the new testcase doesn't exercise this > code. Ok, changed now. I had to keep the ctors[i] = valp; statement in the !preeval block, because otherwise e.g. 20_util/optional/monadic/transform.cc test fails randomly. It was wrong already before the patch, it would adjust TREE_CONSTANT/TREE_SIDE_EFFECTS sometimes on no longer used trees, but with the vector holding pointers to trees rather than trees it is even more severe. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2022-07-27 Jakub Jelinek PR c++/88174 * constexpr.cc (cxx_eval_store_expression): Handle REALPART_EXPR and IMAGPART_EXPR. Change ctors from releasing_vec to auto_vec, adjust all uses. For !preeval, update ctors vector. * g++.dg/cpp1y/constexpr-complex1.C: New test. Jakub --- gcc/cp/constexpr.cc.jj 2022-07-04 12:26:18.147053851 +0200 +++ gcc/cp/constexpr.cc 2022-07-26 17:35:53.100556949 +0200 @@ -5726,6 +5726,20 @@ cxx_eval_store_expression (const constex } break; + case REALPART_EXPR: + gcc_assert (probe == target); + vec_safe_push (refs, probe); + vec_safe_push (refs, TREE_TYPE (probe)); + probe = TREE_OPERAND (probe, 0); + break; + + case IMAGPART_EXPR: + gcc_assert (probe == target); + vec_safe_push (refs, probe); + vec_safe_push (refs, TREE_TYPE (probe)); + probe = TREE_OPERAND (probe, 0); + break; + default: if (evaluated) object = probe; @@ -5764,7 +5778,8 @@ cxx_eval_store_expression (const constex type = TREE_TYPE (object); bool no_zero_init = true; - releasing_vec ctors, indexes; + auto_vec ctors; + releasing_vec indexes; auto_vec index_pos_hints; bool activated_union_member_p = false; bool empty_base = false; @@ -5804,14 +5819,36 @@ cxx_eval_store_expression (const constex *valp = ary_ctor; } - /* If the value of object is already zero-initialized, any new ctors for - subobjects will also be zero-initialized. */ - no_zero_init = CONSTRUCTOR_NO_CLEARING (*valp); - enum tree_code code = TREE_CODE (type); tree reftype = refs->pop(); tree index = refs->pop(); + if (code == COMPLEX_TYPE) + { + if (TREE_CODE (*valp) == COMPLEX_CST) + *valp = build2 (COMPLEX_EXPR, type, TREE_REALPART (*valp), + TREE_IMAGPART (*valp)); + else if (TREE_CODE (*valp) == CONSTRUCTOR + && CONSTRUCTOR_NELTS (*valp) == 0 + && CONSTRUCTOR_NO_CLEARING (*valp)) + { + tree r = build_constructor (reftype, NULL); + CONSTRUCTOR_NO_CLEARING (r) = 1; + *valp = build2 (COMPLEX_EXPR, type, r, r); + } + gcc_assert (TREE_CODE (*valp) == COMPLEX_EXPR); + ctors.safe_push (valp); + vec_safe_push (indexes, index); + valp = &TREE_OPERAND (*valp, TREE_CODE (index) == IMAGPART_EXPR); + gcc_checking_assert (refs->is_empty ()); + type = reftype; + break; + } + + /* If the value of object is already zero-initialized, any new ctors for + subobjects will also be zero-initialized. */ + no_zero_init = CONSTRUCTOR_NO_CLEARING (*valp); + if (code == RECORD_TYPE && is_empty_field (index)) /* Don't build a sub-CONSTRUCTOR for an empty base or field, as they have no data and might have an offset lower than previously declared @@ -5854,7 +5891,7 @@ cxx_eval_store_expression (const constex no_zero_init = true; } - vec_safe_push (ctors, *valp); + ctors.safe_push (valp); vec_safe_push (indexes, index); constructor_elt *cep @@ -5916,11 +5953,11 @@ cxx_eval_store_expression (const constex semantics are not applied on an object under construction. They come into effect when the constructor for the most derived object ends." */ - for (tree elt : *ctors) + for (tree *elt : ctors) if (same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (const_object_being_modified), TREE_TYPE (elt))) + (TREE_TYPE (const_object_being_modified), TREE_TYPE (*elt))) { - fail = TREE_READONLY (elt); + fail = TREE_READONLY (*elt); break; } } @@ -5961,6 +5998,7 @@ cxx_eval_store_expression (const constex valp = ctx->global->values.get (object); for (unsigned i = 0; i < vec_safe_length (indexes); i++) { + ctors[i] = valp; constructor_elt *cep = get_or_insert_ctor_field (*valp, indexes[i], index_pos_hints[i]); valp = &cep->value; @@ -6023,17 +6061,45 @@ cxx_eval_store_expression (const constex CONSTRUCTORs, if any. */ bool c = TREE_CONSTANT (init); bool s = TREE_SIDE_EFFECTS (init); + if (!indexes->is_empty ()) + { + tree last = indexes->last (); + if (TREE_CODE (last) == REALPART_EXPR + || TREE_CODE (last) == IMAGPART_EXPR) + { + /* And canonicalize COMPLEX_EXPR into COMPLEX_CST if + possible. */ + tree *cexpr = ctors.last (); + if (tree c = const_binop (COMPLEX_EXPR, TREE_TYPE (*cexpr), + TREE_OPERAND (*cexpr, 0), + TREE_OPERAND (*cexpr, 1))) + *cexpr = c; + else + { + TREE_CONSTANT (*cexpr) + = (TREE_CONSTANT (TREE_OPERAND (*cexpr, 0)) + & TREE_CONSTANT (TREE_OPERAND (*cexpr, 1))); + TREE_SIDE_EFFECTS (*cexpr) + = (TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 0)) + | TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 1))); + } + c = TREE_CONSTANT (*cexpr); + s = TREE_SIDE_EFFECTS (*cexpr); + } + } if (!c || s || activated_union_member_p) - for (tree elt : *ctors) + for (tree *elt : ctors) { + if (TREE_CODE (*elt) != CONSTRUCTOR) + continue; if (!c) - TREE_CONSTANT (elt) = false; + TREE_CONSTANT (*elt) = false; if (s) - TREE_SIDE_EFFECTS (elt) = true; + TREE_SIDE_EFFECTS (*elt) = true; /* Clear CONSTRUCTOR_NO_CLEARING since we've activated a member of this union. */ - if (TREE_CODE (TREE_TYPE (elt)) == UNION_TYPE) - CONSTRUCTOR_NO_CLEARING (elt) = false; + if (TREE_CODE (TREE_TYPE (*elt)) == UNION_TYPE) + CONSTRUCTOR_NO_CLEARING (*elt) = false; } if (lval) --- gcc/testsuite/g++.dg/cpp1y/constexpr-complex1.C.jj 2022-07-04 17:30:47.884580998 +0200 +++ gcc/testsuite/g++.dg/cpp1y/constexpr-complex1.C 2022-07-04 17:30:47.884580998 +0200 @@ -0,0 +1,24 @@ +// PR c++/88174 +// { dg-do compile { target c++14 } } + +constexpr bool +foo (double x, double y, double z, double w) +{ + __complex__ double a = 0; + __real__ a = x; + __imag__ a = y; +#if __cpp_constexpr >= 201907L + __complex__ double b; + __real__ b = z; +#else + __complex__ double b = z; +#endif + __imag__ b = w; + a += b; + a -= b; + a *= b; + a /= b; + return __real__ a == x && __imag__ a == y; +} + +static_assert (foo (1.0, 2.0, 3.0, 4.0), "");