[clang] [Clang][C++20] Implement constexpr std::bit_cast for bit-fields (PR #74775)

via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 4 17:34:31 PST 2024


================
@@ -404,29 +691,126 @@ constexpr unsigned char identity3b = __builtin_bit_cast(unsigned char, identity3
 
 namespace test_bool {
 
-constexpr bool test_bad_bool = bit_cast<bool>('A'); // expected-error {{must be initialized by a constant expression}} expected-note{{in call}}
+// expected-note at +1 {{cannot be represented in type 'bool'}}
+constexpr bool test_bad_bool = __builtin_bit_cast(bool, 'A'); // expected-error {{must be initialized by a constant expression}}
+
+static_assert(round_trip<signed char>(true));
+static_assert(round_trip<unsigned char>(true));
----------------
sethp wrote:

These tests document the existing behavior, but both this and the `bit_cast<uint8_t>(false)` below are somewhat troublesome in that we're promoting the `bool`'s padding bits to "real" bits (by zero-extension). As I understand it, that's allowed by the spec (padding bits are "unspecified"), but it does mean that we've got to "over-read" `bool`s as being a full `i8` when we convert `bit_cast<bool>((uint8_t)N)` so that we can refuse to produce a constant value if the top bits are non-zero.

It would be more consistent and simplify the implementation a bit to throw an error on `bit_cast<char>(false)` in a constexpr context complaining about attempting to read padding bits, but I've chosen to preserve the existing behavior here in service of backwards compatibility and usability.

https://github.com/llvm/llvm-project/pull/74775


More information about the cfe-commits mailing list