https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108934
Bug ID: 108934 Summary: bit_cast'ing to long double errors out with "the argument cannot be interpreted" since gcc-12 Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: janpmoeller at gmx dot de Target Milestone: --- In gcc-trunk, gcc-12.2 and gcc-12.1, the following code fails to compile, while gcc-11.3 accepts it: ///////////////////////////////////////////////////////////////////////////////////////////////////////////// #include <array> #include <bit> #include <cstdint> using uint64_x_2_t = std::array<std::uint64_t, 2>; using uint32_x_2_t = std::array<std::uint32_t, 2>; using uint16_x_2_t = std::array<std::uint16_t, 2>; static_assert(sizeof(long double) == sizeof(uint64_x_2_t)); static_assert(sizeof(double) == sizeof(uint32_x_2_t)); static_assert(sizeof(float) == sizeof(uint16_x_2_t)); constexpr long double testld = 42.42; constexpr double testd = 42.42; constexpr float testf = 42.42f; constexpr uint64_x_2_t test_uint64_x_2_t{1u, 2u}; constexpr uint32_x_2_t test_uint32_x_2_t{1u, 2u}; constexpr uint16_x_2_t test_uint16_x_2_t{1u, 2u}; constexpr auto ld_to_uint64_x_2_t = std::bit_cast<uint64_x_2_t>(testld); // works! (reverse direction) constexpr auto d_to_uint32_x_2_t = std::bit_cast<uint32_x_2_t>(testd); constexpr auto f_to_uint16_x_2_t = std::bit_cast<uint16_x_2_t>(testf); constexpr auto default_uint64_x_2_t_to_ld = std::bit_cast<long double>(uint64_x_2_t{}); // works! (default initialized) constexpr auto default_uint32_x_2_t_to_d = std::bit_cast<double>(uint32_x_2_t{}); constexpr auto default_uint16_x_2_t_to_f = std::bit_cast<float>(uint16_x_2_t{}); constexpr auto temp_uint64_x_2_t_to_ld = std::bit_cast<long double>(uint64_x_2_t{1u, 2u}); // <= fails constexpr auto temp_uint32_x_2_t_to_d = std::bit_cast<double>(uint32_x_2_t{1u, 2u}); constexpr auto temp_uint16_x_2_t_to_f = std::bit_cast<float>(uint16_x_2_t{1u, 2u}); constexpr auto uint64_x_2_t_to_ld = std::bit_cast<long double>(test_uint64_x_2_t); // <= fails constexpr auto uint32_x_2_t_to_d = std::bit_cast<double>(test_uint32_x_2_t); constexpr auto uint16_x_2_t_to_f = std::bit_cast<float>(test_uint16_x_2_t); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// The compile error for both offending lines is: /usr/include/c++/12/bit:87:33: sorry, unimplemented: ‘__builtin_bit_cast’ cannot be constant evaluated because the argument cannot be interpreted The strange thing is that this error only seems to appear if the array is aggregate-initialized; default initialized arrays do not trigger the error. float and double do not trigger the error either. Replacing std::array with a struct aggregate type behaves the same as the array example above. The reverse direction, i.e. bit_cast'ing from long double to array, seems to be working fine. The above example on compiler explorer: https://godbolt.org/z/ba5d6hEG1