From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id ABBBF3858292; Mon, 18 Dec 2023 14:32:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org ABBBF3858292 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1702909972; bh=pnUbcCRpHKhCGL1Dvx/LglChUug7zCQrkELEcr2RbVo=; h=From:To:Subject:Date:In-Reply-To:References:From; b=xYzo4ck7qvlZj6ehTCG+RVsNg5AzhTEf0PSYfogpkCdLWWtEqv6/7DRC102JDQiXu MIInkT8R5MBNLKdiwxtjJsvRaojQUKtwsEjwwWSXyVKBWTTFsgOtubQIoba1UKBek7 E2///oRM6m5sLBk4/em1fP93AMzJrbyeoiEmSqRY= From: "dangelog at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/113060] std::variant converting constructor/assignment is non-conforming after P2280? Date: Mon, 18 Dec 2023 14:32:51 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: libstdc++ X-Bugzilla-Version: 14.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: dangelog at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D113060 --- Comment #2 from Giuseppe D'Angelo --- (In reply to Jonathan Wakely from comment #1) > (In reply to Giuseppe D'Angelo from comment #0) > > GCC 14 implements P2280 (see #106650).=20 >=20 > N.B. if you say "Bug 106650" or "PR 106650" or "bug #106650" or pretty mu= ch > anything except just #106650 then bugzilla makes it a clickable link :) D'oh!=20 > > it seems that variant should indeed accept construction from IC. >=20 > I'm not convinced that this change to the semantics of std::variant was an > intended side effect of https://wg21.link/P2280 -- I think I'd prefer if = the > committee confirmed it. Ok, I'll raise the question to LEWG. Or maybe EWG? > The standard doesn't say that it _should_ work in a constant expression, = it > seems like you're assuming that because it's now possible to implement it= so > that it works, that it's required to work. >=20 > My reading of [variant.ctor] p14 is that "some invented variable x" is no= t a > constant expression, so using std::declval as a stand-in for "some invent= ed > variable" is fine. But it does say how you get that x, you get it from the statement: Tj x[] =3D {std=E2=80=8B::=E2=80=8Bforward(t)}; Nowhere in there's a call to declval. My reasoning is simply that if you sp= ell FUN out for Ti =3D float, something like this (although the standard doesn't really specify the signature of FUN, which is not ideal): template auto FUN_float(T &&t) { float x[] =3D {std=E2=80=8B::=E2=80=8Bforward(t)}; } then FUN_float(IC{}) is well-formed after P2280. Note that in general IC c; // not const!!! float f{c}; // OK is well-formed, and this is even before P2280. What seems to have changed w= ith P2280 is that references do not disqualify expressions from being constant,= and thus we can now detect this case a requires-expression that uses references. > If we made this change, then some cases that compile today would become > ill-formed, e.g. see PR 113007. Under your reading, conversion from the > constant 42 would be valid for both int64_t and double, and so the > initialization would be ill-formed. But it would be well-formed when usin= g a > non-constant int equal to 42. Are you sure it would? FUN_double(42) should be still ill-formed (!), due to narrowing.=20 My reasoning, in the context of P0870 (is_convertible_without_narrowing), is that int->double requires a lvalue-to-rvalue conversion, and then this kick= s in https://eel.is/c++draft/expr.const#5.9 , disqualifying `t` from being treat= ed as a constant expression. So then the list-initialization of `x` triggers narrowing. This is different from IC->double, where there's no lvalue-to-rvalue conver= sion (!), it's described here https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0870r5.html#ch5.9 Testcase: https://gcc.godbolt.org/z/rfvnfvYzs > Apart from the fact it would be a breaking change, the difference in > behaviour between runtime and compile time would be surprising. It would > also mean that std::is_constructible would be misleading: it would say you > can construct variant from 42, but when you try to do that = it > would fail to compile. Sure, I'm really struggling at squaring the P2280 rules with detecting narrowing conversions, but I'm not sure if this would actually break. (And = I'm not sure if something _else_ would break instead.)=