Skip to content

Commit 255a99c

Browse files
authored
[APInt] Fix APInt constructions where value does not fit bitwidth (NFCI) (#80309)
This fixes all the places that hit the new assertion added in #106524 in tests. That is, cases where the value passed to the APInt constructor is not an N-bit signed/unsigned integer, where N is the bit width and signedness is determined by the isSigned flag. The fixes either set the correct value for isSigned, set the implicitTrunc flag, or perform more calculations inside APInt. Note that the assertion is currently still disabled by default, so this patch is mostly NFC.
1 parent 3ae6b57 commit 255a99c

31 files changed

+103
-64
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6755,7 +6755,7 @@ class Sema final : public SemaBase {
67556755

67566756
ExprResult BuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK);
67576757
ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
6758-
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
6758+
ExprResult ActOnIntegerConstant(SourceLocation Loc, int64_t Val);
67596759

67606760
bool CheckLoopHintExpr(Expr *E, SourceLocation Loc, bool AllowZero);
67616761

clang/lib/AST/ByteCode/IntegralAP.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ template <bool Signed> class IntegralAP final {
6161

6262
IntegralAP(APInt V) : V(V) {}
6363
/// Arbitrary value for uninitialized variables.
64-
IntegralAP() : IntegralAP(-1, 3) {}
64+
IntegralAP() : IntegralAP(Signed ? -1 : 7, 3) {}
6565

6666
IntegralAP operator-() const { return IntegralAP(-V); }
6767
IntegralAP operator-(const IntegralAP &Other) const {
@@ -112,7 +112,10 @@ template <bool Signed> class IntegralAP final {
112112

113113
template <unsigned Bits, bool InputSigned>
114114
static IntegralAP from(Integral<Bits, InputSigned> I, unsigned BitWidth) {
115-
APInt Copy = APInt(BitWidth, static_cast<uint64_t>(I), InputSigned);
115+
// TODO: Avoid implicit trunc?
116+
// See https://github.com/llvm/llvm-project/issues/112510.
117+
APInt Copy = APInt(BitWidth, static_cast<uint64_t>(I), InputSigned,
118+
/*implicitTrunc=*/true);
116119

117120
return IntegralAP<Signed>(Copy);
118121
}

clang/lib/CodeGen/CGVTT.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,9 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
8585
cast<llvm::StructType>(VTable->getValueType())
8686
->getElementType(AddressPoint.VTableIndex));
8787
unsigned Offset = ComponentSize * AddressPoint.AddressPointIndex;
88-
llvm::ConstantRange InRange(llvm::APInt(32, -Offset, true),
89-
llvm::APInt(32, VTableSize - Offset, true));
88+
llvm::ConstantRange InRange(
89+
llvm::APInt(32, (int)-Offset, true),
90+
llvm::APInt(32, (int)(VTableSize - Offset), true));
9091
llvm::Constant *Init = llvm::ConstantExpr::getGetElementPtr(
9192
VTable->getValueType(), VTable, Idxs, /*InBounds=*/true, InRange);
9293

clang/lib/CodeGen/ItaniumCXXABI.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,8 +2099,9 @@ ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
20992099
unsigned VTableSize =
21002100
ComponentSize * Layout.getVTableSize(AddressPoint.VTableIndex);
21012101
unsigned Offset = ComponentSize * AddressPoint.AddressPointIndex;
2102-
llvm::ConstantRange InRange(llvm::APInt(32, -Offset, true),
2103-
llvm::APInt(32, VTableSize - Offset, true));
2102+
llvm::ConstantRange InRange(
2103+
llvm::APInt(32, (int)-Offset, true),
2104+
llvm::APInt(32, (int)(VTableSize - Offset), true));
21042105
return llvm::ConstantExpr::getGetElementPtr(
21052106
VTable->getValueType(), VTable, Indices, /*InBounds=*/true, InRange);
21062107
}

clang/lib/Parse/ParseInit.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,9 +436,9 @@ ExprResult Parser::createEmbedExpr() {
436436
ASTContext &Context = Actions.getASTContext();
437437
SourceLocation StartLoc = ConsumeAnnotationToken();
438438
if (Data->BinaryData.size() == 1) {
439-
Res = IntegerLiteral::Create(Context,
440-
llvm::APInt(CHAR_BIT, Data->BinaryData.back()),
441-
Context.UnsignedCharTy, StartLoc);
439+
Res = IntegerLiteral::Create(
440+
Context, llvm::APInt(CHAR_BIT, (unsigned char)Data->BinaryData.back()),
441+
Context.UnsignedCharTy, StartLoc);
442442
} else {
443443
auto CreateStringLiteralFromStringRef = [&](StringRef Str, QualType Ty) {
444444
llvm::APSInt ArraySize =

clang/lib/Sema/SemaExpr.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3598,9 +3598,10 @@ ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) {
35983598
Lit, Tok.getLocation());
35993599
}
36003600

3601-
ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, uint64_t Val) {
3601+
ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, int64_t Val) {
36023602
unsigned IntSize = Context.getTargetInfo().getIntWidth();
3603-
return IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val),
3603+
return IntegerLiteral::Create(Context,
3604+
llvm::APInt(IntSize, Val, /*isSigned=*/true),
36043605
Context.IntTy, Loc);
36053606
}
36063607

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5697,7 +5697,9 @@ StmtResult SemaOpenMP::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
56975697
llvm_unreachable("unhandled unary increment operator");
56985698
}
56995699
Step = IntegerLiteral::Create(
5700-
Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5700+
Ctx,
5701+
llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction, /*isSigned=*/true),
5702+
LogicalTy, {});
57015703
} else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
57025704
if (IncBin->getOpcode() == BO_AddAssign) {
57035705
Step = IncBin->getRHS();

lldb/source/Expression/DWARFExpression.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -860,10 +860,12 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
860860
// TODO: Implement a real typed stack, and store the genericness of the value
861861
// there.
862862
auto to_generic = [&](auto v) {
863+
// TODO: Avoid implicit trunc?
864+
// See https://github.com/llvm/llvm-project/issues/112510.
863865
bool is_signed = std::is_signed<decltype(v)>::value;
864-
return Scalar(llvm::APSInt(
865-
llvm::APInt(8 * opcodes.GetAddressByteSize(), v, is_signed),
866-
!is_signed));
866+
return Scalar(llvm::APSInt(llvm::APInt(8 * opcodes.GetAddressByteSize(), v,
867+
is_signed, /*implicitTrunc=*/true),
868+
!is_signed));
867869
};
868870

869871
// The default kind is a memory location. This is updated by any

llvm/include/llvm/ADT/APFixedPoint.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,9 @@ class APFixedPoint {
168168
}
169169

170170
APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema)
171-
: APFixedPoint(APInt(Sema.getWidth(), Val, Sema.isSigned()), Sema) {}
171+
: APFixedPoint(APInt(Sema.getWidth(), Val, Sema.isSigned(),
172+
/*implicitTrunc=*/true),
173+
Sema) {}
172174

173175
// Zero initialization.
174176
APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {}

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,8 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
888888
APInt Offset = APInt(
889889
BitWidth,
890890
DL.getIndexedOffsetInType(
891-
SrcElemTy, ArrayRef((Value *const *)Ops.data() + 1, Ops.size() - 1)));
891+
SrcElemTy, ArrayRef((Value *const *)Ops.data() + 1, Ops.size() - 1)),
892+
/*isSigned=*/true, /*implicitTrunc=*/true);
892893

893894
std::optional<ConstantRange> InRange = GEP->getInRange();
894895
if (InRange)

0 commit comments

Comments
 (0)