From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1734) id D87703858C50; Fri, 10 Feb 2023 00:06:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D87703858C50 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1675987599; bh=braCVUpdFM4DVO3JmRId03z72wNiWlowAWxs562Lk0k=; h=From:To:Subject:Date:From; b=f4mBObChektj4NW7LBrLEBZnUBRyd7FuY1iFduWTcDyD73W8vNkpUMuq/qgiyFbUP tFVIfNJJDQ/rWCVi+k/P8/Hn7DygPujKKnL4n61PIRUVn38B9cwJNPXo3oFj/s2s1o e/TO3MDK8NCV+pMoCSL3SfBZEekzzYX42m5ipCnQ= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Marek Polacek To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-5763] c++: ICE initing lifetime-extended constexpr var [PR107079] X-Act-Checkin: gcc X-Git-Author: Marek Polacek X-Git-Refname: refs/heads/trunk X-Git-Oldrev: 125b57aa67400388a496c2c0c40d9c8c55e0c94a X-Git-Newrev: 67b82bc1b29b82e4577df9491793624f3a8eb12f Message-Id: <20230210000639.D87703858C50@sourceware.org> Date: Fri, 10 Feb 2023 00:06:39 +0000 (GMT) List-Id: https://gcc.gnu.org/g:67b82bc1b29b82e4577df9491793624f3a8eb12f commit r13-5763-g67b82bc1b29b82e4577df9491793624f3a8eb12f Author: Marek Polacek Date: Wed Feb 8 14:02:48 2023 -0500 c++: ICE initing lifetime-extended constexpr var [PR107079] We ICE on the simple: struct X { const X* x = this; }; constexpr const X& x = X{}; where store_init_value initializes 'x' with &TARGET_EXPR }> but we must lifetime-extend via extend_ref_init_temps and we get _ZGR1x_.x = (const struct X *) & >>>;, (const struct X &) &_ZGR1x_; Since 'x' was declared constexpr, we do cxx_constant_init and we hit the preeval code added in r269003 while evaluating the INIT_EXPR: _ZGR1x_.x = (const struct X *) & >>> but we have no ctx.ctor or ctx.object here so lookup_placeholder won't find anything that could replace X and we ICE on 7861 /* A placeholder without a referent. We can get here when 7862 checking whether NSDMIs are noexcept, or in massage_init_elt; 7863 just say it's non-constant for now. */ 7864 gcc_assert (ctx->quiet); because cxx_constant_init means !ctx->quiet. It's not correct that there isn't a referent. I think the following patch is a pretty straightforward fix: pass the _ZGR var down to maybe_constant_init so that it can replace the PLACEHOLDER_EXPR with _ZGR1x_. The commented assert in the test doesn't pass: we complain that _ZGR1x_ isn't a constexpr variable because we don't implement DR2126 (PR101588). PR c++/107079 gcc/cp/ChangeLog: * call.cc (set_up_extended_ref_temp): Pass var to maybe_constant_init. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-nsdmi2.C: New test. Diff: --- gcc/cp/call.cc | 2 +- gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi2.C | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index f7c5d9da94b..a349d8e79db 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -13583,7 +13583,7 @@ set_up_extended_ref_temp (tree decl, tree expr, vec **cleanups, /* If the initializer is constant, put it in DECL_INITIAL so we get static initialization and use in constant expressions. */ - init = maybe_constant_init (expr); + init = maybe_constant_init (expr, var, /*manifestly_const_eval=*/true); /* As in store_init_value. */ init = cp_fully_fold (init); if (TREE_CONSTANT (init)) diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi2.C new file mode 100644 index 00000000000..d711b8051c0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi2.C @@ -0,0 +1,9 @@ +// PR c++/107079 +// { dg-do compile { target c++11 } } + +struct X { + const X* x = this; +}; +constexpr const X& x = X{}; +// TODO: The assert should pass once we implement DR2126 (c++/101588). +//static_assert(x.x == &x);