public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/113007] New: `std::variant` converting constructor and `operator=` compile while the C++ Standard says they must not
@ 2023-12-13 21:11 paul.skeptic at yandex dot ru
  2023-12-13 21:15 ` [Bug libstdc++/113007] " pinskia at gcc dot gnu.org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: paul.skeptic at yandex dot ru @ 2023-12-13 21:11 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113007

            Bug ID: 113007
           Summary: `std::variant` converting constructor and `operator=`
                    compile while the C++ Standard says they must not
           Product: gcc
           Version: 13.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: paul.skeptic at yandex dot ru
  Target Milestone: ---

According to [variant.ctor] (https://eel.is/c++draft/variant.ctor, also see
https://en.cppreference.com/w/cpp/utility/variant/variant) converting
constructor

    template<class T>
    constexpr variant(T&& t) noexcept(/*...*/);

determines the alternative to construct as if by selecting an overload for
`F(std​::​forward<T>(​t))` from an overload set `F(T_j)` where `T_j` are types
of the alternatives,
e.g. for `std::variant<std::monostate, bool, int64_t, double>` the overload set
would be

    void F(std::monostate) {}
    void F(bool) {}
    void F(int64_t) {}
    void F(double) {}


In violation of the standard this code compiles with GCC and libstdc++
(https://godbolt.org/z/fd8xa1bqM):

    std::variant<std::monostate, bool, int64_t, double> v = 42;

while overload resolution of `F()` fails:

    F(42); // error: ambiguous confused_john_travolta.gif

Compiler output:

<source>: In function 'int main()':
<source>:14:4: error: call of overloaded 'F(int)' is ambiguous
   14 |   F(42);
      |   ~^~~~
<source>:6:6: note: candidate: 'void F(bool)'
    6 | void F(bool) {}
      |      ^
<source>:7:6: note: candidate: 'void F(int64_t)'
    7 | void F(int64_t) {}
      |      ^
<source>:8:6: note: candidate: 'void F(double)'
    8 | void F(double) {}
      |      ^


Also the same applies to converting assignment operator

    template<class T>
    constexpr variant& operator=(T&& t) noexcept(/*...*/);

see [variant.assign] (https://eel.is/c++draft/variant.assign, also
https://en.cppreference.com/w/cpp/utility/variant/operator%3D).

Among libc++, libstdc++ and MSVC standard libraries only MSVC standard library
gets it according to the standard so you can look at it for reference.

See corresponding bug for libc++:
https://github.com/llvm/llvm-project/issues/75323

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-02-19 10:13 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-13 21:11 [Bug libstdc++/113007] New: `std::variant` converting constructor and `operator=` compile while the C++ Standard says they must not paul.skeptic at yandex dot ru
2023-12-13 21:15 ` [Bug libstdc++/113007] " pinskia at gcc dot gnu.org
2023-12-14  1:03 ` redi at gcc dot gnu.org
2023-12-14  1:06 ` redi at gcc dot gnu.org
2023-12-14 10:58 ` paul.skeptic at yandex dot ru
2023-12-14 14:18 ` redi at gcc dot gnu.org
2023-12-14 14:20 ` redi at gcc dot gnu.org
2023-12-14 15:44 ` paul.skeptic at yandex dot ru
2024-02-19 10:13 ` de34 at live dot cn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).