[clang] [clang][bytecode] Fix bit casts to IntAP types (PR #158509)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Sun Sep 14 13:31:31 PDT 2025
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/158509
They were left out.
Fixes #153920
>From 7ec071c268f2fd13e190fff38e302c7aec3c1b0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Sun, 14 Sep 2025 22:20:38 +0200
Subject: [PATCH] [clang][bytecode] Fix bit casts to IntAP types
---
.../lib/AST/ByteCode/InterpBuiltinBitCast.cpp | 28 +++++++++----
clang/test/AST/ByteCode/builtin-bit-cast.cpp | 41 +++++++++++++++++++
2 files changed, 62 insertions(+), 7 deletions(-)
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 at +2 {{constexpr variable 'test_nullptr_bad' must be initialized by a constant expression}}
// both-note at +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
+
+}
More information about the cfe-commits
mailing list