aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Checkers
diff options
context:
space:
mode:
authorFangyi Zhou <me@fangyi.io>2025-04-25 12:32:38 +0100
committerGitHub <noreply@github.com>2025-04-25 13:32:38 +0200
commit317763580fa92a05ba04f4a04677124acb958ea3 (patch)
treecadcb478767ec933dcfcfcae0eace45c3a0c9bbd /clang/lib/StaticAnalyzer/Checkers
parentd775b911c90e631f5cc332c07474f7121564e25b (diff)
downloadllvm-317763580fa92a05ba04f4a04677124acb958ea3.zip
llvm-317763580fa92a05ba04f4a04677124acb958ea3.tar.gz
llvm-317763580fa92a05ba04f4a04677124acb958ea3.tar.bz2
[clang][analyzer][NFC] Add a helper for conjuring symbols at call events (#137182)
Per suggestion in https://github.com/llvm/llvm-project/pull/128251#discussion_r2055916229, adding a new helper function in `SValBuilder` to conjure a symbol when given a `CallEvent`. Tested manually (with assertions) that the `LocationContext *` obtained from the `CallEvent` are identical to those passed in the original argument.
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp32
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp11
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp4
6 files changed, 20 insertions, 36 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 39dcaf0..f6b5ad8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -1514,8 +1514,7 @@ void CStringChecker::evalCopyCommon(CheckerContext &C, const CallEvent &Call,
// If we don't know how much we copied, we can at least
// conjure a return value for later.
if (lastElement.isUnknown())
- lastElement = C.getSValBuilder().conjureSymbolVal(
- nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
+ lastElement = C.getSValBuilder().conjureSymbolVal(Call, C.blockCount());
// The byte after the last byte copied is the return value.
state = state->BindExpr(Call.getOriginExpr(), LCtx, lastElement);
@@ -1665,8 +1664,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallEvent &Call,
State = CheckBufferAccess(C, State, Left, Size, AccessKind::read, CK);
if (State) {
// The return value is the comparison result, which we don't know.
- SVal CmpV = Builder.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx,
- C.blockCount());
+ SVal CmpV = Builder.conjureSymbolVal(Call, C.blockCount());
State = State->BindExpr(Call.getOriginExpr(), LCtx, CmpV);
C.addTransition(State);
}
@@ -1769,8 +1767,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C,
// no guarantee the full string length will actually be returned.
// All we know is the return value is the min of the string length
// and the limit. This is better than nothing.
- result = C.getSValBuilder().conjureSymbolVal(
- nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
+ result = C.getSValBuilder().conjureSymbolVal(Call, C.blockCount());
NonLoc resultNL = result.castAs<NonLoc>();
if (strLengthNL) {
@@ -1793,8 +1790,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C,
// If we don't know the length of the string, conjure a return
// value, so it can be used in constraints, at least.
if (result.isUnknown()) {
- result = C.getSValBuilder().conjureSymbolVal(
- nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
+ result = C.getSValBuilder().conjureSymbolVal(Call, C.blockCount());
}
}
@@ -2261,8 +2257,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallEvent &Call,
// If this is a stpcpy-style copy, but we were unable to check for a buffer
// overflow, we still need a result. Conjure a return value.
if (ReturnEnd && Result.isUnknown()) {
- Result = svalBuilder.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx,
- C.blockCount());
+ Result = svalBuilder.conjureSymbolVal(Call, C.blockCount());
}
}
// Set the return value.
@@ -2361,8 +2356,7 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallEvent &Call,
const StringLiteral *RightStrLiteral =
getCStringLiteral(C, state, Right.Expression, RightVal);
bool canComputeResult = false;
- SVal resultVal = svalBuilder.conjureSymbolVal(nullptr, Call.getOriginExpr(),
- LCtx, C.blockCount());
+ SVal resultVal = svalBuilder.conjureSymbolVal(Call, C.blockCount());
if (LeftStrLiteral && RightStrLiteral) {
StringRef LeftStrRef = LeftStrLiteral->getString();
@@ -2467,16 +2461,13 @@ void CStringChecker::evalStrsep(CheckerContext &C,
// Overwrite the search string pointer. The new value is either an address
// further along in the same string, or NULL if there are no more tokens.
- State =
- State->bindLoc(*SearchStrLoc,
- SVB.conjureSymbolVal(getTag(), Call.getOriginExpr(),
- LCtx, CharPtrTy, C.blockCount()),
- LCtx);
+ State = State->bindLoc(*SearchStrLoc,
+ SVB.conjureSymbolVal(Call, C.blockCount(), getTag()),
+ LCtx);
} else {
assert(SearchStrVal.isUnknown());
// Conjure a symbolic value. It's the best we can do.
- Result = SVB.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx,
- C.blockCount());
+ Result = SVB.conjureSymbolVal(Call, C.blockCount());
}
// Set the return value, and finish.
@@ -2519,8 +2510,7 @@ void CStringChecker::evalStdCopyCommon(CheckerContext &C,
SValBuilder &SVB = C.getSValBuilder();
- SVal ResultVal =
- SVB.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
+ SVal ResultVal = SVB.conjureSymbolVal(Call, C.blockCount());
State = State->BindExpr(Call.getOriginExpr(), LCtx, ResultVal);
C.addTransition(State);
diff --git a/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp
index 6076a6b..74eda4e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp
@@ -130,8 +130,7 @@ void ErrnoTesterChecker::evalSetErrnoIfErrorRange(CheckerContext &C,
ProgramStateRef StateFailure = State->BindExpr(
Call.getOriginExpr(), C.getLocationContext(), SVB.makeIntVal(1, true));
- DefinedOrUnknownSVal ErrnoVal = SVB.conjureSymbolVal(
- nullptr, Call.getOriginExpr(), C.getLocationContext(), C.blockCount());
+ DefinedOrUnknownSVal ErrnoVal = SVB.conjureSymbolVal(Call, C.blockCount());
StateFailure = StateFailure->assume(ErrnoVal, true);
assert(StateFailure && "Failed to assume on an initial value.");
StateFailure =
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index cc1ced7..85e22da 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -931,8 +931,7 @@ bool RetainCountChecker::evalCall(const CallEvent &Call,
if (RetVal.isUnknown() ||
(hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
SValBuilder &SVB = C.getSValBuilder();
- RetVal =
- SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
+ RetVal = SVB.conjureSymbolVal(Call, C.blockCount());
}
// Bind the value.
diff --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
index 321388a..d56e683 100644
--- a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
@@ -851,9 +851,8 @@ void SmartPtrModeling::handleBoolConversion(const CallEvent &Call,
if (InnerPointerType.isNull())
return;
- const LocationContext *LC = C.getLocationContext();
InnerPointerVal = C.getSValBuilder().conjureSymbolVal(
- CallExpr, LC, InnerPointerType, C.blockCount());
+ Call, InnerPointerType, C.blockCount());
State = State->set<TrackedRegionMap>(ThisRegion, InnerPointerVal);
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 9c0b79a..17227a2 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -584,11 +584,9 @@ class StdLibraryFunctionsChecker
const Summary &Summary,
CheckerContext &C) const override {
SValBuilder &SVB = C.getSValBuilder();
- NonLoc ErrnoSVal =
- SVB.conjureSymbolVal(&Tag, Call.getOriginExpr(),
- C.getLocationContext(), C.getASTContext().IntTy,
- C.blockCount())
- .castAs<NonLoc>();
+ NonLoc ErrnoSVal = SVB.conjureSymbolVal(Call, C.getASTContext().IntTy,
+ C.blockCount(), &Tag)
+ .castAs<NonLoc>();
return errno_modeling::setErrnoForStdFailure(State, C, ErrnoSVal);
}
};
@@ -1481,8 +1479,7 @@ bool StdLibraryFunctionsChecker::evalCall(const CallEvent &Call,
ProgramStateRef State = C.getState();
const LocationContext *LC = C.getLocationContext();
const auto *CE = cast<CallExpr>(Call.getOriginExpr());
- SVal V = C.getSValBuilder().conjureSymbolVal(
- CE, LC, CE->getType().getCanonicalType(), C.blockCount());
+ SVal V = C.getSValBuilder().conjureSymbolVal(Call, C.blockCount());
State = State->BindExpr(CE, LC, V);
C.addTransition(State);
diff --git a/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp
index fefe846..7d465ee 100644
--- a/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp
@@ -206,8 +206,8 @@ void InvalidPtrChecker::postPreviousReturnInvalidatingCall(
const auto *CE = cast<CallExpr>(Call.getOriginExpr());
// Function call will return a pointer to the new symbolic region.
- DefinedOrUnknownSVal RetVal = C.getSValBuilder().conjureSymbolVal(
- CE, LCtx, CE->getType(), C.blockCount());
+ DefinedOrUnknownSVal RetVal =
+ C.getSValBuilder().conjureSymbolVal(Call, C.blockCount());
State = State->BindExpr(CE, LCtx, RetVal);
const auto *SymRegOfRetVal =