================
@@ -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

Reply via email to