Skip to content

Commit a5d9ba6

Browse files
authored
[clang][bytecode] Error on bitcasts to bool that aren't 0 or 1 (llvm#149996)
This is also what the current interpreter does.
1 parent 4ae9fdc commit a5d9ba6

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

clang/lib/AST/ByteCode/Interp.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3557,12 +3557,22 @@ inline bool BitCastPrim(InterpState &S, CodePtr OpPC, bool TargetIsUCharOrByte,
35573557
Floating Result = S.allocFloat(*Sem);
35583558
Floating::bitcastFromMemory(Buff.data(), *Sem, &Result);
35593559
S.Stk.push<Floating>(Result);
3560-
3561-
// S.Stk.push<Floating>(T::bitcastFromMemory(Buff.data(), *Sem));
35623560
} else if constexpr (needsAlloc<T>()) {
35633561
T Result = S.allocAP<T>(ResultBitWidth);
35643562
T::bitcastFromMemory(Buff.data(), ResultBitWidth, &Result);
35653563
S.Stk.push<T>(Result);
3564+
} else if constexpr (std::is_same_v<T, Boolean>) {
3565+
// Only allow to cast single-byte integers to bool if they are either 0
3566+
// or 1.
3567+
assert(FullBitWidth.getQuantity() == 8);
3568+
auto Val = static_cast<unsigned int>(Buff[0]);
3569+
if (Val > 1) {
3570+
S.FFDiag(S.Current->getSource(OpPC),
3571+
diag::note_constexpr_bit_cast_unrepresentable_value)
3572+
<< S.getASTContext().BoolTy << Val;
3573+
return false;
3574+
}
3575+
S.Stk.push<T>(T::bitcastFromMemory(Buff.data(), ResultBitWidth));
35663576
} else {
35673577
assert(!Sem);
35683578
S.Stk.push<T>(T::bitcastFromMemory(Buff.data(), ResultBitWidth));

clang/test/AST/ByteCode/builtin-bit-cast.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ typedef __INTPTR_TYPE__ intptr_t;
2222
static_assert(sizeof(int) == 4);
2323
static_assert(sizeof(long long) == 8);
2424

25+
26+
constexpr bool test_bad_bool = __builtin_bit_cast(bool, (char)0xff); // both-error {{must be initialized by a constant expression}} \
27+
// both-note {{value 255 cannot be represented in type 'bool'}}
28+
2529
template <class To, class From>
2630
constexpr To bit_cast(const From &from) {
2731
static_assert(sizeof(To) == sizeof(From));

0 commit comments

Comments
 (0)