https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105027
Bug ID: 105027 Summary: Missing constraints on std::bit_cast Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- [bit.cast] Constraints (nb. prior to P1719R2 these were specified as SFINAE, but they have been there since the start): (1.1) sizeof(To) == sizeof(From) is true; (1.2) is_trivially_copyable_v<To> is true; and (1.3) is_trivially_copyable_v<From> is true. #include <bit> template<class T, class U> concept BitCastable = requires(U u) { std::bit_cast<T>(u); }; static_assert(BitCastable<int, unsigned>); // OK static_assert(BitCastable<int, char>); // #1: different size struct A { A(A const&); int i; }; static_assert(BitCastable<int, A>); // #2: not trivially copyable #1 and #2 are erroneously accepted although the corresponding call to std::bit_cast would fail internally; MSVC and clang (with libc++) correctly reject. static_assert(BitCastable<long, int()>); // #3: see below int f(); long l = std::bit_cast<long>(f); // #4 By my reading of [temp.deduct] #3 should be a hard error, since sizeof(int()) is not only invalid; it is not SFINAE. However, compilers that allow it (gcc everywhere, MSVC and clang as SFINAE) should then reject either by SFINAE, or as having the incorrect size, or since function types are not trivially copyable; gcc/libstdc++ does not and also accepts #4, decaying the function reference to a function pointer; clang/libstdc++ rejects within its own __builtin_bit_cast.