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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
