[clang] [clang][bytecode] Don't use trunc() to increase APInt bitWidth (PR #180536)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 9 07:05:30 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
`FieldDecl::getBitWidthValue()` can return a value higher than the type size of the bit field. We need to account for that.
---
Full diff: https://github.com/llvm/llvm-project/pull/180536.diff
2 Files Affected:
- (modified) clang/lib/AST/ByteCode/Interp.h (+12-14)
- (modified) clang/test/AST/ByteCode/intap.cpp (+8)
``````````diff
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index ca5b1fd6bf072..0d0f19e4f61dd 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -1703,16 +1703,15 @@ bool InitBitField(InterpState &S, CodePtr OpPC, const Record::Field *F) {
const Pointer &Field = Ptr.atField(F->Offset);
+ unsigned BitWidth = std::min(F->Decl->getBitWidthValue(), Value.bitWidth());
if constexpr (needsAlloc<T>()) {
T Result = S.allocAP<T>(Value.bitWidth());
- if (T::isSigned())
- Result.copy(Value.toAPSInt()
- .trunc(F->Decl->getBitWidthValue())
- .sextOrTrunc(Value.bitWidth()));
+ if constexpr (T::isSigned())
+ Result.copy(
+ Value.toAPSInt().trunc(BitWidth).sextOrTrunc(Value.bitWidth()));
else
- Result.copy(Value.toAPSInt()
- .trunc(F->Decl->getBitWidthValue())
- .zextOrTrunc(Value.bitWidth()));
+ Result.copy(
+ Value.toAPSInt().trunc(BitWidth).zextOrTrunc(Value.bitWidth()));
Field.deref<T>() = Result;
} else {
@@ -1735,16 +1734,15 @@ bool InitBitFieldActivate(InterpState &S, CodePtr OpPC,
const Pointer &Field = Ptr.atField(F->Offset);
+ unsigned BitWidth = std::min(F->Decl->getBitWidthValue(), Value.bitWidth());
if constexpr (needsAlloc<T>()) {
T Result = S.allocAP<T>(Value.bitWidth());
- if (T::isSigned())
- Result.copy(Value.toAPSInt()
- .trunc(F->Decl->getBitWidthValue())
- .sextOrTrunc(Value.bitWidth()));
+ if constexpr (T::isSigned())
+ Result.copy(
+ Value.toAPSInt().trunc(BitWidth).sextOrTrunc(Value.bitWidth()));
else
- Result.copy(Value.toAPSInt()
- .trunc(F->Decl->getBitWidthValue())
- .zextOrTrunc(Value.bitWidth()));
+ Result.copy(
+ Value.toAPSInt().trunc(BitWidth).zextOrTrunc(Value.bitWidth()));
Field.deref<T>() = Result;
} else {
diff --git a/clang/test/AST/ByteCode/intap.cpp b/clang/test/AST/ByteCode/intap.cpp
index efb60cb0abffe..051774a92e168 100644
--- a/clang/test/AST/ByteCode/intap.cpp
+++ b/clang/test/AST/ByteCode/intap.cpp
@@ -102,6 +102,14 @@ namespace PointerArithmeticOverflow {
// both-note {{cannot refer to element 3402}}
}
+namespace BitfieldWidth {
+ struct S {
+ __int128 foo : 1234; // both-warning {{width of bit-field 'foo' (1'234 bits) exceeds the width of its type}}
+ };
+ constexpr S s{100};
+ static_assert(s.foo == 100, "");
+}
+
namespace i128 {
constexpr int128_t I128_1 = 12;
``````````
</details>
https://github.com/llvm/llvm-project/pull/180536
More information about the cfe-commits
mailing list