From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by sourceware.org (Postfix) with ESMTP id BE19E385E020 for ; Tue, 5 Jan 2021 16:00:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org BE19E385E020 Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-234-jP5_KA98MbaZEUL2oWvi1g-1; Tue, 05 Jan 2021 11:00:49 -0500 X-MC-Unique: jP5_KA98MbaZEUL2oWvi1g-1 Received: by mail-qk1-f198.google.com with SMTP id u9so179646qkk.5 for ; Tue, 05 Jan 2021 08:00:49 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=fKEBt6ZY4p1AqT3r69+GbBxuLmsoUDZHI2ESG0S4fkc=; b=bjBwvJbPrcJMUWk55wO70XqbYAz05t8K3qU/cSM89XDMCjmUIChyLMKccpIvrUIT4f 1IvOVYAgg+eglzSC+YWKuC+6xMsf8/KU4jtmtoSyxd4WAT2XSCrObQD2xa96RKl2kuY4 jqrwQMoOX9eTNwOAH24jIzcP3TQIDj2e8Y9qBLd7CXli5PmiB8o7kthbLKNMLFFlaA3o RhZp99h9zQ7N9k7gjzBAXTKv3BxvyXzDNiMLuw0vIbkP9BBDWdHETJNSuAoGZfq1md+L f8LGja6hz6p399D2oP6SK14Ek1DU/BV8eFfMFNkJb7zh2b+Dd/i0Kzh4FbRVUStrhcfX x2EQ== X-Gm-Message-State: AOAM533kYKZXftpJEQftFPNByDrq7goW/EEsxqmGpJzaZ62Rw5eR+ezi jNWrbsfxHKgITqekWKuzK7tZ+2PcIIGjRFfmIr25whSzJIr0rUsdxkjVgGqTCLTCJYn/iQUulcG HebFBVV3c6/vSuIrs1rurZ9MMj2Pj1iLHK7QfzP0RZwt91okwIbc+voaSIBtSpAYLLg== X-Received: by 2002:a37:3d1:: with SMTP id 200mr205462qkd.30.1609862448289; Tue, 05 Jan 2021 08:00:48 -0800 (PST) X-Google-Smtp-Source: ABdhPJy9MCbzuRBYzvyNSy2wLQLsVeEOObnuUqE+sdHMXUfIbBkjt4A9Miwb2fINY4nmvLuk6ce5Fg== X-Received: by 2002:a37:3d1:: with SMTP id 200mr205419qkd.30.1609862447844; Tue, 05 Jan 2021 08:00:47 -0800 (PST) Received: from [192.168.1.148] (209-6-216-142.s141.c3-0.smr-cbr1.sbo-smr.ma.cable.rcncustomer.com. [209.6.216.142]) by smtp.gmail.com with ESMTPSA id f134sm202523qke.85.2021.01.05.08.00.46 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 05 Jan 2021 08:00:46 -0800 (PST) Subject: Re: [PATCH] c++, v2: Fix ICE with __builtin_bit_cast [PR98469] To: Jakub Jelinek Cc: gcc-patches@gcc.gnu.org References: <20201230091343.GU3788@tucnak> <20210104204820.GB725145@tucnak> <989b7d53-25fe-dc11-63a1-deaf18df615c@redhat.com> <20210105152624.GR725145@tucnak> From: Jason Merrill Message-ID: <61706f9e-abfd-e8b9-45a0-349fe9971d3b@redhat.com> Date: Tue, 5 Jan 2021 11:00:46 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.4.3 MIME-Version: 1.0 In-Reply-To: <20210105152624.GR725145@tucnak> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-10.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, NICE_REPLY_A, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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-List-Received-Date: Tue, 05 Jan 2021 16:00:52 -0000 On 1/5/21 10:26 AM, Jakub Jelinek wrote: > On Mon, Jan 04, 2021 at 04:01:25PM -0500, Jason Merrill via Gcc-patches wrote: >> On 1/4/21 3:48 PM, Jakub Jelinek wrote: >>> On Mon, Jan 04, 2021 at 03:44:46PM -0500, Jason Merrill wrote: >>>> This change is OK, but part of the problem is that we're trying to do >>>> overload resolution for an S copy/move constructor, which we shouldn't be >>>> because bit_cast is a prvalue, so in C++17 and up we should use it to >>>> directly initialize the target without any implied constructor call. >>>> >>>> It seems we're mishandling this because the code in >>>> build_special_member_call specifically looks for TARGET_EXPR or CONSTRUCTOR, >>>> and BIT_CAST_EXPR is neither of those. >>>> >>>> Wrapping a BIT_CAST_EXPR of aggregate type in a TARGET_EXPR would address >>>> this, and any other places that expect a class prvalue to come in the form >>>> of a TARGET_EXPR. >>> >>> I can try that tomorrow. Won't that cause copying through extra temporary >>> in some cases though, or is that guaranteed to be optimized? >> >> It won't cause any extra copying when it's used to initialize another object >> (like the return value of std::bit_cast). Class prvalues are always >> expressed with a TARGET_EXPR in the front end; the TARGET_EXPR melts away >> when used as an initializer, it only creates a temporary when it's used in >> another way. > > Ok, this version wraps it into a TARGET_EXPR then, it alone fixes the bug, > but I've kept the constexpr.c change too. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? OK. > 2021-01-05 Jakub Jelinek > > PR c++/98469 > * constexpr.c (cxx_eval_constant_expression) : > Punt if lval is true. > * semantics.c (cp_build_bit_cast): Call get_target_expr_sfinae on > the result if it has a class type. > > * g++.dg/cpp2a/bit-cast8.C: New test. > * g++.dg/cpp2a/bit-cast9.C: New test. > > --- gcc/cp/constexpr.c.jj 2021-01-04 10:25:48.750121531 +0100 > +++ gcc/cp/constexpr.c 2021-01-05 11:41:38.315032636 +0100 > @@ -6900,6 +6900,15 @@ cxx_eval_constant_expression (const cons > return t; > > case BIT_CAST_EXPR: > + if (lval) > + { > + if (!ctx->quiet) > + error_at (EXPR_LOCATION (t), > + "address of a call to %qs is not a constant expression", > + "__builtin_bit_cast"); > + *non_constant_p = true; > + return t; > + } > r = cxx_eval_bit_cast (ctx, t, non_constant_p, overflow_p); > break; > > --- gcc/cp/semantics.c.jj 2021-01-04 10:25:48.489124486 +0100 > +++ gcc/cp/semantics.c 2021-01-05 11:27:49.327372582 +0100 > @@ -10761,6 +10761,10 @@ cp_build_bit_cast (location_t loc, tree > > tree ret = build_min (BIT_CAST_EXPR, type, arg); > SET_EXPR_LOCATION (ret, loc); > + > + if (!processing_template_decl && CLASS_TYPE_P (type)) > + ret = get_target_expr_sfinae (ret, complain); > + > return ret; > } > > --- gcc/testsuite/g++.dg/cpp2a/bit-cast8.C.jj 2021-01-05 11:41:38.315032636 +0100 > +++ gcc/testsuite/g++.dg/cpp2a/bit-cast8.C 2021-01-05 11:41:38.315032636 +0100 > @@ -0,0 +1,11 @@ > +// PR c++/98469 > +// { dg-do compile { target c++20 } } > +// { dg-options "-Wall" } > + > +struct S { int s; }; > + > +S > +foo () > +{ > + return __builtin_bit_cast (S, 0); > +} > --- gcc/testsuite/g++.dg/cpp2a/bit-cast9.C.jj 2021-01-05 11:41:38.315032636 +0100 > +++ gcc/testsuite/g++.dg/cpp2a/bit-cast9.C 2021-01-05 11:41:38.315032636 +0100 > @@ -0,0 +1,15 @@ > +// PR c++/98469 > +// { dg-do compile { target c++20 } } > +// { dg-options "-Wall" } > + > +template > +constexpr T > +bit_cast (const F &f) noexcept > +{ > + return __builtin_bit_cast (T, f); > +} > +struct S { int s; }; > +constexpr int foo (const S &x) { return x.s; } > +constexpr int bar () { return foo (bit_cast (0)); } > +constexpr int x = bar (); > +static_assert (!x); > > > Jakub >