From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 7120B385828B; Mon, 18 Dec 2023 09:32:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7120B385828B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1702891950; bh=vtK3fhlpLnYb1YN+EX9ggU11m+ibPnMrB5Z7BuYfJ0U=; h=From:To:Subject:Date:From; b=BxN2Tnhzh7NK366m7JUSG7DRfJtOrOFzN5u4AvhkqkdJ6fbL3P4f61D6Hzg3bx8CS kHARb3osaIMjn/Jj9ZttTSzneDgXA1vGG/e3G5lmaZyFcGv1eec/C01CUZVH4fbsJZ A4BTzq/OPpPMYhklD2T07xKuNADQuX9wwXymib7E= From: "dangelog at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/113060] New: std::variant converting constructor/assignment is non-conforming after P2280? Date: Mon, 18 Dec 2023 09:32:28 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new 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: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: 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 Bug ID: 113060 Summary: std::variant converting constructor/assignment is non-conforming after P2280? Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: dangelog at gmail dot com Target Milestone: --- GCC 14 implements P2280 (see #106650).=20 As a side effect of that, the "narrowing detector" used in std::variant's converting constructor/assignment is now too restrictive. This code: // IC is a type with a constexpr conversion operator using IC =3D std::integral_constant; std::variant v( IC{} ); should work after P2280 (libstdc++ says ill-formed). --- https://eel.is/c++draft/variant.ctor#14 says: > Let Tj be a type that is determined as follows: build an imaginary functi= on FUN(Ti) for each alternative type Ti for which Ti x[] =3D {std=E2=80=8B:= :=E2=80=8Bforward(t)}; is well-formed for some invented variable x. > The overload FUN(Tj) selected by overload resolution for the expression F= UN(std=E2=80=8B::=E2=80=8Bforward(=E2=80=8Bt)) defines the alternative T= j which is the type of the contained value after construction. Right now libstdc++ implements this by means of SFINAE: > https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/st= d/variant#L787-L823 IC is convertible to float, and given the constexpr nature of its conversion operator (to int), it wouldn't be a narrowing conversion: IC ic; float f{ic}; // not narrowing However, using SFINAE means that std::declval() is used to build the "candidate" argument of FUN. declval is not a constexpr function so its returned value is not considered to be usable in constant expressions.=20 The net effect is that `Ti x[] =3D {std=E2=80=8B::=E2=80=8Bforward(t)};`= is considered to be a narrowing conversion ([dcl.init.list], int->float, source is not a constant expression), and FUN(float) rejected. But nowhere does [variant.ctor] talk about using std::declval; if one reimplements the same check with a constraint, then GCC 14 accepts the conversion: template concept FUN_constraint =3D requires(T &&t) { { std::type_identity_t{ std::forward(t) } }; }; template requires FUN_constraint void FUN(float); FUN( IC{} ); // OK https://gcc.godbolt.org/z/xP9z97v35 P2280 is necessary to make this work, because otherwise the usage of a reference in the requires-expression would make `t` again not usable in constant expressions. In conclusion, it seems that variant should in= deed accept construction from IC. (I can't cross-check this report with other compilers as none of them implements P2280 yet.)=