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

Reply via email to