Skip to content

Commit

Permalink
[analyzer][NFC] Migrate nonloc::ConcreteInt to use APSIntPtr (2/4) (l…
Browse files Browse the repository at this point in the history
  • Loading branch information
steakhal authored Dec 19, 2024
1 parent 060d62b commit d0d5101
Show file tree
Hide file tree
Showing 18 changed files with 65 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1206,7 +1206,7 @@ class ElementRegion : public TypedValueRegion {
: TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
Index(Idx) {
assert((!isa<nonloc::ConcreteInt>(Idx) ||
Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
Idx.castAs<nonloc::ConcreteInt>().getValue()->isSigned()) &&
"The index must be signed");
assert(!elementType.isNull() && !elementType->isVoidType() &&
"Invalid region type!");
Expand Down
8 changes: 6 additions & 2 deletions clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/FoldingSet.h"
Expand Down Expand Up @@ -298,9 +299,12 @@ class SymbolVal : public NonLoc {
/// Value representing integer constant.
class ConcreteInt : public NonLoc {
public:
explicit ConcreteInt(const llvm::APSInt &V) : NonLoc(ConcreteIntKind, &V) {}
explicit ConcreteInt(APSIntPtr V) : NonLoc(ConcreteIntKind, V.get()) {}

const llvm::APSInt &getValue() const { return *castDataAs<llvm::APSInt>(); }
APSIntPtr getValue() const {
// This is safe because in the ctor we take a safe APSIntPtr.
return APSIntPtr::unsafeConstructor(castDataAs<llvm::APSInt>());
}

static bool classof(SVal V) { return V.getKind() == ConcreteIntKind; }
};
Expand Down
14 changes: 7 additions & 7 deletions clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
Expand Down Expand Up @@ -241,26 +242,25 @@ computeOffset(ProgramStateRef State, SValBuilder &SVB, SVal Location) {
static std::pair<NonLoc, nonloc::ConcreteInt>
getSimplifiedOffsets(NonLoc offset, nonloc::ConcreteInt extent,
SValBuilder &svalBuilder) {
const llvm::APSInt &extentVal = extent.getValue();
std::optional<nonloc::SymbolVal> SymVal = offset.getAs<nonloc::SymbolVal>();
if (SymVal && SymVal->isExpression()) {
if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SymVal->getSymbol())) {
llvm::APSInt constant =
APSIntType(extent.getValue()).convert(SIE->getRHS());
llvm::APSInt constant = APSIntType(extentVal).convert(SIE->getRHS());
switch (SIE->getOpcode()) {
case BO_Mul:
// The constant should never be 0 here, becasue multiplication by zero
// is simplified by the engine.
if ((extent.getValue() % constant) != 0)
if ((extentVal % constant) != 0)
return std::pair<NonLoc, nonloc::ConcreteInt>(offset, extent);
else
return getSimplifiedOffsets(
nonloc::SymbolVal(SIE->getLHS()),
svalBuilder.makeIntVal(extent.getValue() / constant),
svalBuilder);
svalBuilder.makeIntVal(extentVal / constant), svalBuilder);
case BO_Add:
return getSimplifiedOffsets(
nonloc::SymbolVal(SIE->getLHS()),
svalBuilder.makeIntVal(extent.getValue() - constant), svalBuilder);
svalBuilder.makeIntVal(extentVal - constant), svalBuilder);
default:
break;
}
Expand Down Expand Up @@ -363,7 +363,7 @@ static std::string getRegionName(const SubRegion *Region) {

static std::optional<int64_t> getConcreteValue(NonLoc SV) {
if (auto ConcreteVal = SV.getAs<nonloc::ConcreteInt>()) {
return ConcreteVal->getValue().tryExtValue();
return ConcreteVal->getValue()->tryExtValue();
}
return std::nullopt;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ void CFNumberChecker::checkPreStmt(const CallExpr *CE,
if (!V)
return;

uint64_t NumberKind = V->getValue().getLimitedValue();
uint64_t NumberKind = V->getValue()->getLimitedValue();
std::optional<uint64_t> OptCFNumberSize = GetCFNumberSize(Ctx, NumberKind);

// FIXME: In some cases we can emit an error.
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/StaticAnalyzer/Checkers/BitwiseShiftChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,11 @@ BugReportPtr BitwiseShiftValidator::checkLeftShiftOverflow() {

// We should have already reported a bug if the left operand of the shift was
// negative, so it cannot be negative here.
assert(Left->getValue().isNonNegative());
assert(Left->getValue()->isNonNegative());

const unsigned LeftAvailableBitWidth =
LeftBitWidth - static_cast<unsigned>(ShouldPreserveSignBit);
const unsigned UsedBitsInLeftOperand = Left->getValue().getActiveBits();
const unsigned UsedBitsInLeftOperand = Left->getValue()->getActiveBits();
assert(LeftBitWidth >= UsedBitsInLeftOperand);
const unsigned MaximalAllowedShift =
LeftAvailableBitWidth - UsedBitsInLeftOperand;
Expand All @@ -275,9 +275,9 @@ BugReportPtr BitwiseShiftValidator::checkLeftShiftOverflow() {
if (const auto ConcreteRight = Right.getAs<nonloc::ConcreteInt>()) {
// Here ConcreteRight must contain a small non-negative integer, because
// otherwise one of the earlier checks should've reported a bug.
const unsigned RHS = ConcreteRight->getValue().getExtValue();
const int64_t RHS = ConcreteRight->getValue()->getExtValue();
assert(RHS > MaximalAllowedShift);
const unsigned OverflownBits = RHS - MaximalAllowedShift;
const int64_t OverflownBits = RHS - MaximalAllowedShift;
ShortMsg = formatv(
"The shift '{0} << {1}' overflows the capacity of '{2}'",
Left->getValue(), ConcreteRight->getValue(), LHSTy.getAsString());
Expand Down
8 changes: 5 additions & 3 deletions clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,14 @@ BuiltinFunctionChecker::checkOverflow(CheckerContext &C, SVal RetVal,
unsigned BitWidth = C.getASTContext().getIntWidth(Res);
bool IsUnsigned = Res->isUnsignedIntegerType();

SValBuilder &SVB = C.getSValBuilder();
BasicValueFactory &VF = SVB.getBasicValueFactory();

auto MinValType = llvm::APSInt::getMinValue(BitWidth, IsUnsigned);
auto MaxValType = llvm::APSInt::getMaxValue(BitWidth, IsUnsigned);
nonloc::ConcreteInt MinVal{MinValType};
nonloc::ConcreteInt MaxVal{MaxValType};
nonloc::ConcreteInt MinVal{VF.getValue(MinValType)};
nonloc::ConcreteInt MaxVal{VF.getValue(MaxValType)};

SValBuilder &SVB = C.getSValBuilder();
ProgramStateRef State = C.getState();
SVal IsLeMax = SVB.evalBinOp(State, BO_LE, RetVal, MaxVal, Res);
SVal IsGeMin = SVB.evalBinOp(State, BO_GE, RetVal, MinVal, Res);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ bool PlacementNewChecker::checkPlaceCapacityIsSufficient(
"requires {1} bytes. Current overhead requires the size of {2} "
"bytes",
SizeOfPlaceCI->getValue(), SizeOfTargetCI->getValue(),
SizeOfPlaceCI->getValue() - SizeOfTargetCI->getValue()));
*SizeOfPlaceCI->getValue().get() - SizeOfTargetCI->getValue()));
else if (IsArrayTypeAllocated &&
SizeOfPlaceCI->getValue() == SizeOfTargetCI->getValue())
Msg = std::string(llvm::formatv(
Expand Down
14 changes: 7 additions & 7 deletions clang/lib/StaticAnalyzer/Checkers/Iterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ ProgramStateRef advancePosition(ProgramStateRef State, SVal Iter,
// For concrete integers we can calculate the new position
nonloc::ConcreteInt IntDist = *IntDistOp;

if (IntDist.getValue().isNegative()) {
if (IntDist.getValue()->isNegative()) {
IntDist = nonloc::ConcreteInt(BVF.getValue(-IntDist.getValue()));
BinOp = (BinOp == BO_Add) ? BO_Sub : BO_Add;
}
Expand Down Expand Up @@ -272,19 +272,19 @@ ProgramStateRef assumeNoOverflow(ProgramStateRef State, SymbolRef Sym,
ProgramStateRef NewState = State;

llvm::APSInt Max = AT.getMaxValue() / AT.getValue(Scale);
SVal IsCappedFromAbove =
SVB.evalBinOpNN(State, BO_LE, nonloc::SymbolVal(Sym),
nonloc::ConcreteInt(Max), SVB.getConditionType());
SVal IsCappedFromAbove = SVB.evalBinOpNN(
State, BO_LE, nonloc::SymbolVal(Sym),
nonloc::ConcreteInt(BV.getValue(Max)), SVB.getConditionType());
if (auto DV = IsCappedFromAbove.getAs<DefinedSVal>()) {
NewState = NewState->assume(*DV, true);
if (!NewState)
return State;
}

llvm::APSInt Min = -Max;
SVal IsCappedFromBelow =
SVB.evalBinOpNN(State, BO_GE, nonloc::SymbolVal(Sym),
nonloc::ConcreteInt(Min), SVB.getConditionType());
SVal IsCappedFromBelow = SVB.evalBinOpNN(
State, BO_GE, nonloc::SymbolVal(Sym),
nonloc::ConcreteInt(BV.getValue(Min)), SVB.getConditionType());
if (auto DV = IsCappedFromBelow.getAs<DefinedSVal>()) {
NewState = NewState->assume(*DV, true);
if (!NewState)
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,8 +507,8 @@ void IteratorModeling::processComparison(CheckerContext &C,
OverloadedOperatorKind Op) const {
if (const auto TruthVal = RetVal.getAs<nonloc::ConcreteInt>()) {
if ((State = relateSymbols(State, Sym1, Sym2,
(Op == OO_EqualEqual) ==
(TruthVal->getValue() != 0)))) {
(Op == OO_EqualEqual) ==
(TruthVal->getValue()->getBoolValue())))) {
C.addTransition(State);
} else {
C.generateSink(State, C.getPredecessor());
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void MmapWriteExecChecker::checkPreCall(const CallEvent &Call,
auto ProtLoc = ProtVal.getAs<nonloc::ConcreteInt>();
if (!ProtLoc)
return;
int64_t Prot = ProtLoc->getValue().getSExtValue();
int64_t Prot = ProtLoc->getValue()->getSExtValue();

if ((Prot & ProtWrite) && (Prot & ProtExec)) {
ExplodedNode *N = C.generateNonFatalErrorNode();
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1977,7 +1977,7 @@ StreamChecker::ensureFseekWhenceCorrect(SVal WhenceVal, CheckerContext &C,
if (!CI)
return State;

int64_t X = CI->getValue().getSExtValue();
int64_t X = CI->getValue()->getSExtValue();
if (X == SeekSetVal || X == SeekCurVal || X == SeekEndVal)
return State;

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ getConcreteIntegerValue(const Expr *CondVarExpr, const ExplodedNode *N) {

if (std::optional<SVal> V = getSValForVar(CondVarExpr, N))
if (auto CI = V->getAs<nonloc::ConcreteInt>())
return &CI->getValue();
return CI->getValue().get();
return std::nullopt;
}

Expand Down
8 changes: 3 additions & 5 deletions clang/lib/StaticAnalyzer/Core/MemRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ std::string MemRegion::getDescriptiveName(bool UseQuotes) const {
// Index is a ConcreteInt.
if (auto CI = ER->getIndex().getAs<nonloc::ConcreteInt>()) {
llvm::SmallString<2> Idx;
CI->getValue().toString(Idx);
CI->getValue()->toString(Idx);
ArrayIndices = (llvm::Twine("[") + Idx.str() + "]" + ArrayIndices).str();
}
// Index is symbolic, but may have a descriptive name.
Expand Down Expand Up @@ -1458,9 +1458,7 @@ RegionRawOffset ElementRegion::getAsArrayOffset() const {
SVal index = ER->getIndex();
if (auto CI = index.getAs<nonloc::ConcreteInt>()) {
// Update the offset.
int64_t i = CI->getValue().getSExtValue();

if (i != 0) {
if (int64_t i = CI->getValue()->getSExtValue(); i != 0) {
QualType elemType = ER->getElementType();

// If we are pointing to an incomplete type, go no further.
Expand Down Expand Up @@ -1632,7 +1630,7 @@ static RegionOffset calculateOffset(const MemRegion *R) {
if (SymbolicOffsetBase)
continue;

int64_t i = CI->getValue().getSExtValue();
int64_t i = CI->getValue()->getSExtValue();
// This type size is in bits.
Offset += i * R->getContext().getTypeSize(EleTy);
} else {
Expand Down
6 changes: 2 additions & 4 deletions clang/lib/StaticAnalyzer/Core/ProgramState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,10 @@ SVal ProgramState::getSVal(Loc location, QualType T) const {
// The symbolic value stored to 'x' is actually the conjured
// symbol for the call to foo(); the type of that symbol is 'char',
// not unsigned.
const llvm::APSInt &NewV = getBasicVals().Convert(T, *Int);

APSIntPtr NewV = getBasicVals().Convert(T, *Int);
if (V.getAs<Loc>())
return loc::ConcreteInt(NewV);
else
return nonloc::ConcreteInt(NewV);
return nonloc::ConcreteInt(NewV);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ class EvalCastVisitor : public SValVisitor<EvalCastVisitor, SVal> {

// Integer to bool.
if (CastTy->isBooleanType())
return VB.makeTruthVal(V.getValue().getBoolValue(), CastTy);
return VB.makeTruthVal(V.getValue()->getBoolValue(), CastTy);

// Integer to pointer.
if (CastTy->isIntegralOrEnumerationType())
Expand Down
10 changes: 5 additions & 5 deletions clang/lib/StaticAnalyzer/Core/SVals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ SymbolRef SVal::getAsSymbol(bool IncludeBaseRegions) const {

const llvm::APSInt *SVal::getAsInteger() const {
if (auto CI = getAs<nonloc::ConcreteInt>())
return &CI->getValue();
return CI->getValue().get();
if (auto CI = getAs<loc::ConcreteInt>())
return &CI->getValue();
return nullptr;
Expand Down Expand Up @@ -251,7 +251,7 @@ bool SVal::isConstant(int I) const {
if (std::optional<loc::ConcreteInt> LV = getAs<loc::ConcreteInt>())
return LV->getValue() == I;
if (std::optional<nonloc::ConcreteInt> NV = getAs<nonloc::ConcreteInt>())
return NV->getValue() == I;
return *NV->getValue().get() == I;
return false;
}

Expand Down Expand Up @@ -314,9 +314,9 @@ void SVal::dumpToStream(raw_ostream &os) const {
void NonLoc::dumpToStream(raw_ostream &os) const {
switch (getKind()) {
case nonloc::ConcreteIntKind: {
const auto &Value = castAs<nonloc::ConcreteInt>().getValue();
os << Value << ' ' << (Value.isSigned() ? 'S' : 'U') << Value.getBitWidth()
<< 'b';
APSIntPtr Value = castAs<nonloc::ConcreteInt>().getValue();
os << Value << ' ' << (Value->isSigned() ? 'S' : 'U')
<< Value->getBitWidth() << 'b';
break;
}
case nonloc::SymbolValKind:
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef State,
}

case nonloc::ConcreteIntKind: {
bool b = Cond.castAs<nonloc::ConcreteInt>().getValue() != 0;
bool b = *Cond.castAs<nonloc::ConcreteInt>().getValue().get() != 0;
bool isFeasible = b ? Assumption : !Assumption;
return isFeasible ? State : nullptr;
}
Expand Down
30 changes: 16 additions & 14 deletions clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h"
#include <optional>

Expand Down Expand Up @@ -179,8 +180,7 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS,
if (RHS == 0)
isIdempotent = true;
else if (RHS.isAllOnes()) {
const llvm::APSInt &Result = BasicVals.Convert(resultTy, RHS);
return nonloc::ConcreteInt(Result);
return nonloc::ConcreteInt(BasicVals.Convert(resultTy, RHS));
}
break;
}
Expand Down Expand Up @@ -234,9 +234,10 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS,
static bool isInRelation(BinaryOperator::Opcode Rel, SymbolRef Sym,
llvm::APSInt Bound, ProgramStateRef State) {
SValBuilder &SVB = State->getStateManager().getSValBuilder();
SVal Result =
SVB.evalBinOpNN(State, Rel, nonloc::SymbolVal(Sym),
nonloc::ConcreteInt(Bound), SVB.getConditionType());
BasicValueFactory &BV = SVB.getBasicValueFactory();
SVal Result = SVB.evalBinOpNN(State, Rel, nonloc::SymbolVal(Sym),
nonloc::ConcreteInt(BV.getValue(Bound)),
SVB.getConditionType());
if (auto DV = Result.getAs<DefinedSVal>()) {
return !State->assume(*DV, false);
}
Expand Down Expand Up @@ -273,14 +274,14 @@ static bool isWithinConstantOverflowBounds(llvm::APSInt I) {
return (I <= Max) && (I >= -Max);
}

static std::pair<SymbolRef, llvm::APSInt>
decomposeSymbol(SymbolRef Sym, BasicValueFactory &BV) {
static std::pair<SymbolRef, APSIntPtr> decomposeSymbol(SymbolRef Sym,
BasicValueFactory &BV) {
if (const auto *SymInt = dyn_cast<SymIntExpr>(Sym))
if (BinaryOperator::isAdditiveOp(SymInt->getOpcode()))
return std::make_pair(SymInt->getLHS(),
(SymInt->getOpcode() == BO_Add) ?
(SymInt->getRHS()) :
(-SymInt->getRHS()));
(SymInt->getOpcode() == BO_Add)
? BV.getValue(SymInt->getRHS())
: BV.getValue(-SymInt->getRHS()));

// Fail to decompose: "reduce" the problem to the "$x + 0" case.
return std::make_pair(Sym, BV.getValue(0, Sym->getType()));
Expand Down Expand Up @@ -314,8 +315,9 @@ static NonLoc doRearrangeUnchecked(ProgramStateRef State,
llvm_unreachable("Operation not suitable for unchecked rearrangement!");

if (LSym == RSym)
return SVB.evalBinOpNN(State, Op, nonloc::ConcreteInt(LInt),
nonloc::ConcreteInt(RInt), ResultTy)
return SVB
.evalBinOpNN(State, Op, nonloc::ConcreteInt(BV.getValue(LInt)),
nonloc::ConcreteInt(BV.getValue(RInt)), ResultTy)
.castAs<NonLoc>();

SymbolRef ResultSym = nullptr;
Expand Down Expand Up @@ -1211,7 +1213,7 @@ const llvm::APSInt *SimpleSValBuilder::getConcreteValue(SVal V) {
return &X->getValue();

if (std::optional<nonloc::ConcreteInt> X = V.getAs<nonloc::ConcreteInt>())
return &X->getValue();
return X->getValue().get();

return nullptr;
}
Expand Down

0 comments on commit d0d5101

Please sign in to comment.