Author: Timm Baeder
Date: 2025-07-22T14:23:01+02:00
New Revision: a5d9ba66258e452e4658281bbbd07a2214d4dc51

URL: 
https://github.com/llvm/llvm-project/commit/a5d9ba66258e452e4658281bbbd07a2214d4dc51
DIFF: 
https://github.com/llvm/llvm-project/commit/a5d9ba66258e452e4658281bbbd07a2214d4dc51.diff

LOG: [clang][bytecode] Error on bitcasts to bool that aren't 0 or 1 (#149996)

This is also what the current interpreter does.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Interp.h
    clang/test/AST/ByteCode/builtin-bit-cast.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 7f29200f8617f..b42c7665c3a35 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -3557,12 +3557,22 @@ inline bool BitCastPrim(InterpState &S, CodePtr OpPC, 
bool TargetIsUCharOrByte,
       Floating Result = S.allocFloat(*Sem);
       Floating::bitcastFromMemory(Buff.data(), *Sem, &Result);
       S.Stk.push<Floating>(Result);
-
-      // S.Stk.push<Floating>(T::bitcastFromMemory(Buff.data(), *Sem));
     } else if constexpr (needsAlloc<T>()) {
       T Result = S.allocAP<T>(ResultBitWidth);
       T::bitcastFromMemory(Buff.data(), ResultBitWidth, &Result);
       S.Stk.push<T>(Result);
+    } else if constexpr (std::is_same_v<T, Boolean>) {
+      // Only allow to cast single-byte integers to bool if they are either 0
+      // or 1.
+      assert(FullBitWidth.getQuantity() == 8);
+      auto Val = static_cast<unsigned int>(Buff[0]);
+      if (Val > 1) {
+        S.FFDiag(S.Current->getSource(OpPC),
+                 diag::note_constexpr_bit_cast_unrepresentable_value)
+            << S.getASTContext().BoolTy << Val;
+        return false;
+      }
+      S.Stk.push<T>(T::bitcastFromMemory(Buff.data(), ResultBitWidth));
     } else {
       assert(!Sem);
       S.Stk.push<T>(T::bitcastFromMemory(Buff.data(), ResultBitWidth));

diff  --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp 
b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
index 3c5e89d7d5a74..bc356b0b6e122 100644
--- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp
+++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
@@ -22,6 +22,10 @@ typedef __INTPTR_TYPE__ intptr_t;
 static_assert(sizeof(int) == 4);
 static_assert(sizeof(long long) == 8);
 
+
+constexpr bool test_bad_bool = __builtin_bit_cast(bool, (char)0xff); // 
both-error {{must be initialized by a constant expression}} \
+                                                                     // 
both-note {{value 255 cannot be represented in type 'bool'}}
+
 template <class To, class From>
 constexpr To bit_cast(const From &from) {
   static_assert(sizeof(To) == sizeof(From));


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to