Skip to content

Commit 79e5875

Browse files
committed
[clang][analyzer][NFC] Add a helper for conjuring symbols at call events
Per suggestion in llvm#128251 (comment), 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.
1 parent dde00f5 commit 79e5875

File tree

8 files changed

+42
-45
lines changed

8 files changed

+42
-45
lines changed

clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ class Stmt;
4646

4747
namespace ento {
4848

49+
class CallEvent;
4950
class ConditionTruthVal;
5051
class ProgramStateManager;
5152
class StoreRef;
52-
5353
class SValBuilder {
5454
virtual void anchor();
5555

@@ -209,6 +209,12 @@ class SValBuilder {
209209
const LocationContext *LCtx,
210210
QualType type,
211211
unsigned visitCount);
212+
DefinedOrUnknownSVal conjureSymbolVal(const CallEvent &call, QualType type,
213+
unsigned visitCount,
214+
const void *symbolTag = nullptr);
215+
DefinedOrUnknownSVal conjureSymbolVal(const CallEvent &call,
216+
unsigned visitCount,
217+
const void *symbolTag = nullptr);
212218

213219
/// Conjure a symbol representing heap allocated memory region.
214220
///

clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp

+11-21
Original file line numberDiff line numberDiff line change
@@ -1514,8 +1514,7 @@ void CStringChecker::evalCopyCommon(CheckerContext &C, const CallEvent &Call,
15141514
// If we don't know how much we copied, we can at least
15151515
// conjure a return value for later.
15161516
if (lastElement.isUnknown())
1517-
lastElement = C.getSValBuilder().conjureSymbolVal(
1518-
nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
1517+
lastElement = C.getSValBuilder().conjureSymbolVal(Call, C.blockCount());
15191518

15201519
// The byte after the last byte copied is the return value.
15211520
state = state->BindExpr(Call.getOriginExpr(), LCtx, lastElement);
@@ -1665,8 +1664,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallEvent &Call,
16651664
State = CheckBufferAccess(C, State, Left, Size, AccessKind::read, CK);
16661665
if (State) {
16671666
// The return value is the comparison result, which we don't know.
1668-
SVal CmpV = Builder.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx,
1669-
C.blockCount());
1667+
SVal CmpV = Builder.conjureSymbolVal(Call, C.blockCount());
16701668
State = State->BindExpr(Call.getOriginExpr(), LCtx, CmpV);
16711669
C.addTransition(State);
16721670
}
@@ -1769,8 +1767,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C,
17691767
// no guarantee the full string length will actually be returned.
17701768
// All we know is the return value is the min of the string length
17711769
// and the limit. This is better than nothing.
1772-
result = C.getSValBuilder().conjureSymbolVal(
1773-
nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
1770+
result = C.getSValBuilder().conjureSymbolVal(Call, C.blockCount());
17741771
NonLoc resultNL = result.castAs<NonLoc>();
17751772

17761773
if (strLengthNL) {
@@ -1793,8 +1790,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C,
17931790
// If we don't know the length of the string, conjure a return
17941791
// value, so it can be used in constraints, at least.
17951792
if (result.isUnknown()) {
1796-
result = C.getSValBuilder().conjureSymbolVal(
1797-
nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
1793+
result = C.getSValBuilder().conjureSymbolVal(Call, C.blockCount());
17981794
}
17991795
}
18001796

@@ -2261,8 +2257,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallEvent &Call,
22612257
// If this is a stpcpy-style copy, but we were unable to check for a buffer
22622258
// overflow, we still need a result. Conjure a return value.
22632259
if (ReturnEnd && Result.isUnknown()) {
2264-
Result = svalBuilder.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx,
2265-
C.blockCount());
2260+
Result = svalBuilder.conjureSymbolVal(Call, C.blockCount());
22662261
}
22672262
}
22682263
// Set the return value.
@@ -2361,8 +2356,7 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallEvent &Call,
23612356
const StringLiteral *RightStrLiteral =
23622357
getCStringLiteral(C, state, Right.Expression, RightVal);
23632358
bool canComputeResult = false;
2364-
SVal resultVal = svalBuilder.conjureSymbolVal(nullptr, Call.getOriginExpr(),
2365-
LCtx, C.blockCount());
2359+
SVal resultVal = svalBuilder.conjureSymbolVal(Call, C.blockCount());
23662360

23672361
if (LeftStrLiteral && RightStrLiteral) {
23682362
StringRef LeftStrRef = LeftStrLiteral->getString();
@@ -2467,16 +2461,13 @@ void CStringChecker::evalStrsep(CheckerContext &C,
24672461

24682462
// Overwrite the search string pointer. The new value is either an address
24692463
// further along in the same string, or NULL if there are no more tokens.
2470-
State =
2471-
State->bindLoc(*SearchStrLoc,
2472-
SVB.conjureSymbolVal(getTag(), Call.getOriginExpr(),
2473-
LCtx, CharPtrTy, C.blockCount()),
2474-
LCtx);
2464+
State = State->bindLoc(
2465+
*SearchStrLoc,
2466+
SVB.conjureSymbolVal(Call, CharPtrTy, C.blockCount(), getTag()), LCtx);
24752467
} else {
24762468
assert(SearchStrVal.isUnknown());
24772469
// Conjure a symbolic value. It's the best we can do.
2478-
Result = SVB.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx,
2479-
C.blockCount());
2470+
Result = SVB.conjureSymbolVal(Call, C.blockCount());
24802471
}
24812472

24822473
// Set the return value, and finish.
@@ -2519,8 +2510,7 @@ void CStringChecker::evalStdCopyCommon(CheckerContext &C,
25192510

25202511
SValBuilder &SVB = C.getSValBuilder();
25212512

2522-
SVal ResultVal =
2523-
SVB.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
2513+
SVal ResultVal = SVB.conjureSymbolVal(Call, C.blockCount());
25242514
State = State->BindExpr(Call.getOriginExpr(), LCtx, ResultVal);
25252515

25262516
C.addTransition(State);

clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ void ErrnoTesterChecker::evalSetErrnoIfErrorRange(CheckerContext &C,
130130

131131
ProgramStateRef StateFailure = State->BindExpr(
132132
Call.getOriginExpr(), C.getLocationContext(), SVB.makeIntVal(1, true));
133-
DefinedOrUnknownSVal ErrnoVal = SVB.conjureSymbolVal(
134-
nullptr, Call.getOriginExpr(), C.getLocationContext(), C.blockCount());
133+
DefinedOrUnknownSVal ErrnoVal = SVB.conjureSymbolVal(Call, C.blockCount());
135134
StateFailure = StateFailure->assume(ErrnoVal, true);
136135
assert(StateFailure && "Failed to assume on an initial value.");
137136
StateFailure =

clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -931,8 +931,7 @@ bool RetainCountChecker::evalCall(const CallEvent &Call,
931931
if (RetVal.isUnknown() ||
932932
(hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
933933
SValBuilder &SVB = C.getSValBuilder();
934-
RetVal =
935-
SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
934+
RetVal = SVB.conjureSymbolVal(Call, C.blockCount());
936935
}
937936

938937
// Bind the value.

clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -853,7 +853,7 @@ void SmartPtrModeling::handleBoolConversion(const CallEvent &Call,
853853

854854
const LocationContext *LC = C.getLocationContext();
855855
InnerPointerVal = C.getSValBuilder().conjureSymbolVal(
856-
CallExpr, LC, InnerPointerType, C.blockCount());
856+
Call, InnerPointerType, C.blockCount());
857857
State = State->set<TrackedRegionMap>(ThisRegion, InnerPointerVal);
858858
}
859859

clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -584,11 +584,9 @@ class StdLibraryFunctionsChecker
584584
const Summary &Summary,
585585
CheckerContext &C) const override {
586586
SValBuilder &SVB = C.getSValBuilder();
587-
NonLoc ErrnoSVal =
588-
SVB.conjureSymbolVal(&Tag, Call.getOriginExpr(),
589-
C.getLocationContext(), C.getASTContext().IntTy,
590-
C.blockCount())
591-
.castAs<NonLoc>();
587+
NonLoc ErrnoSVal = SVB.conjureSymbolVal(Call, C.getASTContext().IntTy,
588+
C.blockCount(), &Tag)
589+
.castAs<NonLoc>();
592590
return errno_modeling::setErrnoForStdFailure(State, C, ErrnoSVal);
593591
}
594592
};
@@ -1482,7 +1480,7 @@ bool StdLibraryFunctionsChecker::evalCall(const CallEvent &Call,
14821480
const LocationContext *LC = C.getLocationContext();
14831481
const auto *CE = cast<CallExpr>(Call.getOriginExpr());
14841482
SVal V = C.getSValBuilder().conjureSymbolVal(
1485-
CE, LC, CE->getType().getCanonicalType(), C.blockCount());
1483+
Call, CE->getType().getCanonicalType(), C.blockCount());
14861484
State = State->BindExpr(CE, LC, V);
14871485

14881486
C.addTransition(State);

clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ void InvalidPtrChecker::postPreviousReturnInvalidatingCall(
206206
const auto *CE = cast<CallExpr>(Call.getOriginExpr());
207207

208208
// Function call will return a pointer to the new symbolic region.
209-
DefinedOrUnknownSVal RetVal = C.getSValBuilder().conjureSymbolVal(
210-
CE, LCtx, CE->getType(), C.blockCount());
209+
DefinedOrUnknownSVal RetVal =
210+
C.getSValBuilder().conjureSymbolVal(Call, CE->getType(), C.blockCount());
211211
State = State->BindExpr(CE, LCtx, RetVal);
212212

213213
const auto *SymRegOfRetVal =

clang/lib/StaticAnalyzer/Core/SValBuilder.cpp

+15-10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
2525
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
2626
#include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
27+
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
2728
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
2829
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
2930
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
@@ -192,18 +193,22 @@ DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const Stmt *stmt,
192193
const LocationContext *LCtx,
193194
QualType type,
194195
unsigned visitCount) {
195-
if (type->isNullPtrType())
196-
return makeZeroVal(type);
197-
198-
if (!SymbolManager::canSymbolicate(type))
199-
return UnknownVal();
200-
201-
SymbolRef sym = SymMgr.conjureSymbol(stmt, LCtx, type, visitCount);
196+
return conjureSymbolVal(/*symbolTag=*/nullptr, stmt, LCtx, type, visitCount);
197+
}
202198

203-
if (Loc::isLocType(type))
204-
return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
199+
DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const CallEvent &call,
200+
unsigned visitCount,
201+
const void *symbolTag) {
202+
return conjureSymbolVal(symbolTag, call.getOriginExpr(),
203+
call.getLocationContext(), visitCount);
204+
}
205205

206-
return nonloc::SymbolVal(sym);
206+
DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const CallEvent &call,
207+
QualType type,
208+
unsigned visitCount,
209+
const void *symbolTag) {
210+
return conjureSymbolVal(symbolTag, call.getOriginExpr(),
211+
call.getLocationContext(), type, visitCount);
207212
}
208213

209214
DefinedSVal SValBuilder::getConjuredHeapSymbolVal(const Expr *E,

0 commit comments

Comments
 (0)