Author: Timm Baeder Date: 2025-09-15T08:20:24+02:00 New Revision: 6931bad36c0ddae441d115814022fd5d3cbc554b
URL: https://github.com/llvm/llvm-project/commit/6931bad36c0ddae441d115814022fd5d3cbc554b DIFF: https://github.com/llvm/llvm-project/commit/6931bad36c0ddae441d115814022fd5d3cbc554b.diff LOG: [clang][bytecode] Fix bit casts to IntAP types (#158509) They were left out. Fixes #153920 Added: Modified: clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp clang/test/AST/ByteCode/builtin-bit-cast.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp index feac97d4b1a69..4bd9c66fc9974 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp @@ -441,13 +441,27 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC, if (llvm::sys::IsBigEndianHost) swapBytes(Memory.get(), FullBitWidth.roundToBytes()); - BITCAST_TYPE_SWITCH_FIXED_SIZE(T, { - if (BitWidth.nonZero()) - P.deref<T>() = T::bitcastFromMemory(Memory.get(), T::bitWidth()) - .truncate(BitWidth.getQuantity()); - else - P.deref<T>() = T::zero(); - }); + if (T == PT_IntAPS) { + P.deref<IntegralAP<true>>() = + S.allocAP<IntegralAP<true>>(FullBitWidth.getQuantity()); + IntegralAP<true>::bitcastFromMemory(Memory.get(), + FullBitWidth.getQuantity(), + &P.deref<IntegralAP<true>>()); + } else if (T == PT_IntAP) { + P.deref<IntegralAP<false>>() = + S.allocAP<IntegralAP<false>>(FullBitWidth.getQuantity()); + IntegralAP<false>::bitcastFromMemory(Memory.get(), + FullBitWidth.getQuantity(), + &P.deref<IntegralAP<false>>()); + } else { + BITCAST_TYPE_SWITCH_FIXED_SIZE(T, { + if (BitWidth.nonZero()) + P.deref<T>() = T::bitcastFromMemory(Memory.get(), T::bitWidth()) + .truncate(BitWidth.getQuantity()); + else + P.deref<T>() = T::zero(); + }); + } P.initialize(); return true; }); diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp index bc356b0b6e122..fede780fd66ec 100644 --- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp +++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp @@ -529,3 +529,44 @@ constexpr const intptr_t &returns_local() { return 0L; } // both-error@+2 {{constexpr variable 'test_nullptr_bad' must be initialized by a constant expression}} // both-note@+1 {{read of temporary whose lifetime has ended}} constexpr nullptr_t test_nullptr_bad = __builtin_bit_cast(nullptr_t, returns_local()); + +namespace VectorCast { + typedef unsigned X __attribute__ ((vector_size (64))); + typedef unsigned __int128 Y __attribute__ ((vector_size (64))); + constexpr int test() { + X x = {0}; + Y y = x; + + X x2 = y; + + return 0; + } + static_assert(test() == 0); + + typedef int X2 __attribute__ ((vector_size (64))); + typedef __int128 Y2 __attribute__ ((vector_size (64))); + constexpr int test2() { + X2 x = {0}; + Y2 y = x; + + X2 x2 = y; + + return 0; + } + static_assert(test2() == 0); + + struct S { + unsigned __int128 a : 3; + }; + constexpr S s = __builtin_bit_cast(S, (__int128)12); // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{constexpr bit_cast involving bit-field is not yet supported}} \ + // ref-note {{declared here}} +#if LITTLE_END + static_assert(s.a == 4); // ref-error {{not an integral constant expression}} \ + // ref-note {{initializer of 's' is not a constant expression}} +#else + static_assert(s.a == 0); // ref-error {{not an integral constant expression}} \ + // ref-note {{initializer of 's' is not a constant expression}} +#endif + +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits