================ @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s +// RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s -fno-signed-char +// RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu %s + +// This is separate from constexpr-builtin-bit-cast.cpp because clangd17 seems to behave +// poorly around __BitInt(N) types, and this isolates that unfortunate behavior to one file +// +// hopefully a future clangd will not crash or lose track of its syntax highlighting, at which +// point the "bit_precise" namespace ought to be merged back into *bit-cast.cpp. + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define LITTLE_END 1 +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define LITTLE_END 0 +#else +# error "huh?" +#endif + +using uint8_t = unsigned char; + +template <class To, class From> +constexpr To bit_cast(const From &from) { + static_assert(sizeof(To) == sizeof(From)); + return __builtin_bit_cast(To, from); +} + +namespace bit_precise { +// ok so it's a little bit of a lie to say we don't support _BitInt in any casts; we do in fact +// support casting _from_ a _BitInt(N), at least some of the time +static_assert(bit_cast<uint8_t, _BitInt(8)>(0xff) == 0xff); +template <int N> struct bytes { uint8_t b[N]; }; +static_assert(bit_cast<bytes<2>, _BitInt(12)>(0xff).b[(LITTLE_END ? 0 : /* fixme */ 0)] == 0xff); +static_assert(bit_cast<bytes<4>, _BitInt(24)>(0xff).b[(LITTLE_END ? 0 : /* fixme */ 2)] == 0xff); ---------------- sethp wrote:
These tests *also* document the existing (buggy) behavior; I don't expect there's a lot of people out there using constexpr `std::bit_cast` on `_BitInt(N)` types, but if there are they're having a bad time with it. That said, I took pains to preserve the existing behavior to try and make this change purely "additive"—to the best of my ability I tried to preserve the property that no code that previously compiled without error (including badly formed constructs such as these) would start producing an error. That's a pretty strong stance though, that I went with because I couldn't find details on `clang`'s backwards compatibility policy. I'm happy to soften it: in this case, I would probably prefer to produce an error instead of a value from `APValueToBufferConverter` when it encounders a `_BitInt(N)` type and thereby make it consistently unsupported pending future work. https://github.com/llvm/llvm-project/pull/74775 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits