k-wisniewski created this revision.
k-wisniewski added reviewers: dergachev.a, dcoughlin, zaks.anna.
k-wisniewski added a subscriber: cfe-commits.
Hi,
I've been working on a checker that uses RegionChanges interface and needed to
access to LocationContext. Another change is an easy way to obtain arguments'
SVals from StackFrameCtx, with which the function/method has been called. In my
opinion having that might prove useful for creating future checkers so I
publish it here for review and discussion. Obvoiusly, this needs some
improvement, but I'll be more than happy to hear community's opinion about the
current version, as I wasn't sure if my changes fit into architecture etc.
Also: this is my first public contribution to clang. so if there are any
annoying aspects of it (like the list of subscribers being to broad, bad forma,
wrong metadata etc.) - sorry!
https://reviews.llvm.org/D26588
Files:
include/clang/StaticAnalyzer/Core/Checker.h
include/clang/StaticAnalyzer/Core/CheckerManager.h
include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
lib/StaticAnalyzer/Checkers/CStringChecker.cpp
lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
lib/StaticAnalyzer/Checkers/MallocChecker.cpp
lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
lib/StaticAnalyzer/Core/CheckerManager.cpp
lib/StaticAnalyzer/Core/ExprEngine.cpp
lib/StaticAnalyzer/Core/ExprEngineC.cpp
lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
lib/StaticAnalyzer/Core/ProgramState.cpp
Index: lib/StaticAnalyzer/Core/ProgramState.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ProgramState.cpp
+++ lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -111,24 +111,29 @@
return ConstraintMgr->removeDeadBindings(Result, SymReaper);
}
-ProgramStateRef ProgramState::bindLoc(Loc LV, SVal V, bool notifyChanges) const {
+ProgramStateRef ProgramState::bindLoc(Loc LV,
+ SVal V,
+ const LocationContext *LCtx,
+ bool notifyChanges) const {
ProgramStateManager &Mgr = getStateManager();
ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
LV, V));
const MemRegion *MR = LV.getAsRegion();
if (MR && Mgr.getOwningEngine() && notifyChanges)
- return Mgr.getOwningEngine()->processRegionChange(newState, MR);
+ return Mgr.getOwningEngine()->processRegionChange(newState, MR, LCtx);
return newState;
}
-ProgramStateRef ProgramState::bindDefault(SVal loc, SVal V) const {
+ProgramStateRef ProgramState::bindDefault(SVal loc,
+ SVal V,
+ const LocationContext *LCtx) const {
ProgramStateManager &Mgr = getStateManager();
const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion();
const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
ProgramStateRef new_state = makeWithStore(newStore);
return Mgr.getOwningEngine() ?
- Mgr.getOwningEngine()->processRegionChange(new_state, R) :
+ Mgr.getOwningEngine()->processRegionChange(new_state, R, LCtx) :
new_state;
}
@@ -202,7 +207,7 @@
}
return Eng->processRegionChanges(newState, IS, TopLevelInvalidated,
- Invalidated, Call);
+ Invalidated, Call, LCtx);
}
const StoreRef &newStore =
Index: lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -115,11 +115,11 @@
SymbolRef Sym = SymMgr.conjureSymbol(elem, LCtx, T,
currBldrCtx->blockCount());
SVal V = svalBuilder.makeLoc(Sym);
- hasElems = hasElems->bindLoc(elementV, V);
+ hasElems = hasElems->bindLoc(elementV, V, LCtx);
// Bind the location to 'nil' on the false branch.
SVal nilV = svalBuilder.makeIntVal(0, T);
- noElems = noElems->bindLoc(elementV, nilV);
+ noElems = noElems->bindLoc(elementV, nilV, LCtx);
}
// Create the new nodes.
Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -317,7 +317,7 @@
// actually make things worse. Placement new makes this tricky as well,
// since it's then possible to be initializing one part of a multi-
// dimensional array.
- State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal);
+ State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal, LCtx);
Bldr.generateNode(CE, *I, State, /*tag=*/nullptr,
ProgramPoint::PreStmtKind);
}
@@ -548,7 +548,7 @@
SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(),
currBldrCtx->blockCount());
ProgramStateRef state = Pred->getState();
- state = state->bindLoc(state->getLValue(VD, LCtx), V);
+ state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx);
StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
Bldr.generateNode(CS, Pred, state);
@@ -603,7 +603,7 @@
InitVal = State->getSVal(SizeExpr, LocCtxt);
}
- State = State->bindLoc(FieldLoc, InitVal);
+ State = State->bindLoc(FieldLoc, InitVal, LocCtxt);
}
// Decay the Loc into an RValue, because there might be a
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -226,12 +226,13 @@
if (capturedR != originalR) {
SVal originalV;
+ const LocationContext *LCtx = Pred->getLocationContext();
if (copyExpr) {
- originalV = State->getSVal(copyExpr, Pred->getLocationContext());
+ originalV = State->getSVal(copyExpr, LCtx);
} else {
originalV = State->getSVal(loc::MemRegionVal(originalR));
}
- State = State->bindLoc(loc::MemRegionVal(capturedR), originalV);
+ State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, LCtx);
}
}
}
@@ -478,7 +479,7 @@
} else {
assert(isa<InitListExpr>(Init));
Loc CLLoc = State->getLValue(CL, LCtx);
- State = State->bindLoc(CLLoc, V);
+ State = State->bindLoc(CLLoc, V, LCtx);
// Compound literal expressions are a GNU extension in C++.
// Unlike in C, where CLs are lvalues, in C++ CLs are prvalues,
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -238,7 +238,7 @@
if (V.isUnknown())
V = getSValBuilder().conjureSymbolVal(Result, LC, TR->getValueType(),
currBldrCtx->blockCount());
- State = State->bindLoc(Reg, V);
+ State = State->bindLoc(Reg, V, LC);
// Re-apply the casts (from innermost to outermost) for type sanity.
for (SmallVectorImpl<const CastExpr *>::reverse_iterator I = Casts.rbegin(),
@@ -262,18 +262,21 @@
return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption);
}
-bool ExprEngine::wantsRegionChangeUpdate(ProgramStateRef state) {
- return getCheckerManager().wantsRegionChangeUpdate(state);
+bool ExprEngine::wantsRegionChangeUpdate(ProgramStateRef state,
+ const LocationContext *LCtx) {
+ return getCheckerManager().wantsRegionChangeUpdate(state, LCtx);
}
ProgramStateRef
ExprEngine::processRegionChanges(ProgramStateRef state,
const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> Explicits,
ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call) {
+ const CallEvent *Call,
+ const LocationContext *LCtx) {
return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
- Explicits, Regions, Call);
+ Explicits, Regions,
+ Call, LCtx);
}
void ExprEngine::printState(raw_ostream &Out, ProgramStateRef State,
@@ -2133,7 +2136,9 @@
// (3) We are binding to a MemRegion with stack storage that the store
// does not understand.
ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State,
- SVal Loc, SVal Val) {
+ SVal Loc,
+ SVal Val,
+ const LocationContext *LCtx) {
// Are we storing to something that causes the value to "escape"?
bool escapes = true;
@@ -2149,7 +2154,7 @@
// same state.
SVal StoredVal = State->getSVal(regionLoc->getRegion());
if (StoredVal != Val)
- escapes = (State == (State->bindLoc(*regionLoc, Val)));
+ escapes = (State == (State->bindLoc(*regionLoc, Val, LCtx)));
}
}
@@ -2246,7 +2251,7 @@
const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/nullptr,
/*tag*/nullptr);
ProgramStateRef state = Pred->getState();
- state = processPointerEscapedOnBind(state, location, Val);
+ state = processPointerEscapedOnBind(state, location, Val, LC);
Bldr.generateNode(L, state, Pred);
return;
}
@@ -2256,13 +2261,13 @@
ExplodedNode *PredI = *I;
ProgramStateRef state = PredI->getState();
- state = processPointerEscapedOnBind(state, location, Val);
+ state = processPointerEscapedOnBind(state, location, Val, LC);
// When binding the value, pass on the hint that this is a initialization.
// For initializations, we do not need to inform clients of region
// changes.
state = state->bindLoc(location.castAs<Loc>(),
- Val, /* notifyChanges = */ !atDeclInit);
+ Val, LC, /* notifyChanges = */ !atDeclInit);
const MemRegion *LocReg = nullptr;
if (Optional<loc::MemRegionVal> LocRegVal =
@@ -2488,7 +2493,7 @@
assert (!X.getAs<NonLoc>()); // Should be an Lval, or unknown, undef.
if (Optional<Loc> LV = X.getAs<Loc>())
- state = state->bindLoc(*LV, UnknownVal());
+ state = state->bindLoc(*LV, UnknownVal(), Pred->getLocationContext());
}
Bldr.generateNode(A, Pred, state);
Index: lib/StaticAnalyzer/Core/CheckerManager.cpp
===================================================================
--- lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -519,9 +519,9 @@
}
/// \brief True if at least one checker wants to check region changes.
-bool CheckerManager::wantsRegionChangeUpdate(ProgramStateRef state) {
+bool CheckerManager::wantsRegionChangeUpdate(ProgramStateRef state, const LocationContext *LCtx) {
for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i)
- if (RegionChangesCheckers[i].WantUpdateFn(state))
+ if (RegionChangesCheckers[i].WantUpdateFn(state, LCtx))
return true;
return false;
@@ -533,14 +533,16 @@
const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call) {
+ const CallEvent *Call,
+ const LocationContext *LCtx) {
for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) {
// If any checker declares the state infeasible (or if it starts that way),
// bail out.
if (!state)
return nullptr;
state = RegionChangesCheckers[i].CheckFn(state, invalidated,
- ExplicitRegions, Regions, Call);
+ ExplicitRegions, Regions,
+ Call, LCtx);
}
return state;
}
Index: lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -2647,9 +2647,10 @@
const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call) const;
+ const CallEvent *Call,
+ const LocationContext* LCtx) const;
- bool wantsRegionChangeUpdate(ProgramStateRef state) const {
+ bool wantsRegionChangeUpdate(ProgramStateRef state, const LocationContext *LCtx) const {
return true;
}
@@ -3638,7 +3639,7 @@
// same state.
SVal StoredVal = state->getSVal(regionLoc->getRegion());
if (StoredVal != val)
- escapes = (state == (state->bindLoc(*regionLoc, val)));
+ escapes = (state == (state->bindLoc(*regionLoc, val, C.getLocationContext())));
}
if (!escapes) {
// Case 4: We do not currently model what happens when a symbol is
@@ -3708,7 +3709,8 @@
const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call) const {
+ const CallEvent *Call,
+ const LocationContext *LCtx) const {
if (!invalidated)
return state;
Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1155,7 +1155,7 @@
State = State->BindExpr(CE, C.getLocationContext(), RetVal);
// Fill the region with the initialization value.
- State = State->bindDefault(RetVal, Init);
+ State = State->bindDefault(RetVal, Init, LCtx);
// Set the region's extent equal to the Size parameter.
const SymbolicRegion *R =
Index: lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
+++ lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
@@ -51,9 +51,9 @@
State->getSVal(SVB.getCXXThis(MD, LCtx->getCurrentStackFrame()));
auto Param = SVB.makeLoc(State->getRegion(MD->getParamDecl(0), LCtx));
auto ParamVal = State->getSVal(Param);
- ProgramStateRef SelfAssignState = State->bindLoc(Param, ThisVal);
+ ProgramStateRef SelfAssignState = State->bindLoc(Param, ThisVal, LCtx);
C.addTransition(SelfAssignState);
- ProgramStateRef NonSelfAssignState = State->bindLoc(Param, ParamVal);
+ ProgramStateRef NonSelfAssignState = State->bindLoc(Param, ParamVal, LCtx);
C.addTransition(NonSelfAssignState);
}
Index: lib/StaticAnalyzer/Checkers/CStringChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -62,14 +62,15 @@
void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const;
void checkLiveSymbols(ProgramStateRef state, SymbolReaper &SR) const;
void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
- bool wantsRegionChangeUpdate(ProgramStateRef state) const;
+ bool wantsRegionChangeUpdate(ProgramStateRef state, const LocationContext *LCtx) const;
ProgramStateRef
checkRegionChanges(ProgramStateRef state,
const InvalidatedSymbols *,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call) const;
+ const CallEvent *Call,
+ const LocationContext *LCtx) const;
typedef void (CStringChecker::*FnCheck)(CheckerContext &,
const CallExpr *) const;
@@ -1944,8 +1945,12 @@
// 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(), CE, LCtx, CharPtrTy,
- C.blockCount()));
+ SVB.conjureSymbolVal(getTag(),
+ CE,
+ LCtx,
+ CharPtrTy,
+ C.blockCount()),
+ LCtx);
} else {
assert(SearchStrVal.isUnknown());
// Conjure a symbolic value. It's the best we can do.
@@ -2112,7 +2117,8 @@
C.addTransition(state);
}
-bool CStringChecker::wantsRegionChangeUpdate(ProgramStateRef state) const {
+bool CStringChecker::wantsRegionChangeUpdate(ProgramStateRef state,
+ const LocationContext *LCtx) const {
CStringLengthTy Entries = state->get<CStringLength>();
return !Entries.isEmpty();
}
@@ -2122,7 +2128,8 @@
const InvalidatedSymbols *,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call) const {
+ const CallEvent *Call,
+ const LocationContext *LCtx) const {
CStringLengthTy Entries = state->get<CStringLength>();
if (Entries.isEmpty())
return state;
Index: include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -126,26 +126,29 @@
/// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
/// region change should trigger a processRegionChanges update.
- virtual bool wantsRegionChangeUpdate(ProgramStateRef state) = 0;
+ virtual bool wantsRegionChangeUpdate(ProgramStateRef state,
+ const LocationContext *LCtx) = 0;
/// processRegionChanges - Called by ProgramStateManager whenever a change is
/// made to the store. Used to update checkers that track region values.
virtual ProgramStateRef
processRegionChanges(ProgramStateRef state,
const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call) = 0;
+ const CallEvent *Call,
+ const LocationContext *LCtx) = 0;
inline ProgramStateRef
processRegionChange(ProgramStateRef state,
- const MemRegion* MR) {
- return processRegionChanges(state, nullptr, MR, MR, nullptr);
+ const MemRegion* MR,
+ const LocationContext *LCtx) {
+ return processRegionChanges(state, nullptr, MR, MR, nullptr, LCtx);
}
virtual ProgramStateRef
- processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val) = 0;
+ processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val, const LocationContext *LCtx) = 0;
virtual ProgramStateRef
notifyCheckersOfPointerEscape(ProgramStateRef State,
Index: include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -230,11 +230,12 @@
ProgramStateRef bindLoc(Loc location,
SVal V,
+ const LocationContext *LCtx,
bool notifyChanges = true) const;
- ProgramStateRef bindLoc(SVal location, SVal V) const;
+ ProgramStateRef bindLoc(SVal location, SVal V, const LocationContext *LCtx) const;
- ProgramStateRef bindDefault(SVal loc, SVal V) const;
+ ProgramStateRef bindDefault(SVal loc, SVal V, const LocationContext *LCtx) const;
ProgramStateRef killBinding(Loc LV) const;
@@ -293,6 +294,10 @@
/// Get the lvalue for an array index.
SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
+ /// Get the symbolic value of arguments used in a call
+ /// that created the given stack frame
+ SVal getArgSVal(const StackFrameContext *SFC, const unsigned ArgIdx) const;
+
/// Returns the SVal bound to the statement 'S' in the state's environment.
SVal getSVal(const Stmt *S, const LocationContext *LCtx) const;
@@ -684,9 +689,9 @@
->assumeWithinInclusiveRangeDual(this, Val.castAs<NonLoc>(), From, To);
}
-inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
+inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V, const LocationContext *LCtx) const {
if (Optional<Loc> L = LV.getAs<Loc>())
- return bindLoc(*L, V);
+ return bindLoc(*L, V, LCtx);
return this;
}
@@ -724,6 +729,28 @@
return UnknownVal();
}
+inline SVal ProgramState::getArgSVal(const StackFrameContext *SFC,
+ const unsigned ArgIdx) const {
+ const FunctionDecl *FunctionDecl = SFC->getDecl()->getAsFunction();
+ unsigned NumArgs = FunctionDecl->getNumParams();
+ assert(ArgIdx < NumArgs && "Arg access out of range!");
+
+ if (SFC->inTopFrame()) {
+ // if we are in the top frame we don't have any arguments bound in the store
+ // because the call wasn't modeled in the first place.
+ const VarDecl *ArgDecl = FunctionDecl->parameters()[ArgIdx];
+ const Loc ArgLoc = getLValue(ArgDecl, SFC);
+ return getSVal(ArgLoc);
+ } else {
+ // in this case we need to ask the environment as the arguments' memory
+ // region may have been purged as no longer needed.
+ const Stmt *callSite = SFC->getCallSite();
+ const CallExpr *callSiteExpr = dyn_cast<CallExpr>(callSite);
+ const Expr *argExpr = callSiteExpr->getArg(ArgIdx);
+ return getSVal(argExpr, SFC->getParent());
+ }
+}
+
inline SVal ProgramState::getSVal(const Stmt *Ex,
const LocationContext *LCtx) const{
return Env.getSVal(EnvironmentEntry(Ex, LCtx),
Index: include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -288,16 +288,17 @@
/// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
/// region change should trigger a processRegionChanges update.
- bool wantsRegionChangeUpdate(ProgramStateRef state) override;
+ bool wantsRegionChangeUpdate(ProgramStateRef state, const LocationContext *LCtx) override;
/// processRegionChanges - Called by ProgramStateManager whenever a change is made
/// to the store. Used to update checkers that track region values.
ProgramStateRef
processRegionChanges(ProgramStateRef state,
const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call) override;
+ const CallEvent *Call,
+ const LocationContext *LCtx) override;
/// printState - Called by ProgramStateManager to print checker-specific data.
void printState(raw_ostream &Out, ProgramStateRef State,
@@ -510,7 +511,9 @@
/// Call PointerEscape callback when a value escapes as a result of bind.
ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State,
- SVal Loc, SVal Val) override;
+ SVal Loc,
+ SVal Val,
+ const LocationContext *LCtx) override;
/// Call PointerEscape callback when a value escapes as a result of
/// region invalidation.
/// \param[in] ITraits Specifies invalidation traits for regions/symbols.
Index: include/clang/StaticAnalyzer/Core/CheckerManager.h
===================================================================
--- include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -323,7 +323,7 @@
ProgramPoint::Kind K);
/// \brief True if at least one checker wants to check region changes.
- bool wantsRegionChangeUpdate(ProgramStateRef state);
+ bool wantsRegionChangeUpdate(ProgramStateRef state, const LocationContext *LCtx);
/// \brief Run checkers for region changes.
///
@@ -341,7 +341,8 @@
const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call);
+ const CallEvent *Call,
+ const LocationContext *LCtx);
/// \brief Run checkers when pointers escape.
///
@@ -449,10 +450,11 @@
const InvalidatedSymbols *symbols,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call)>
+ const CallEvent *Call,
+ const LocationContext *LCtx)>
CheckRegionChangesFunc;
- typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
+ typedef CheckerFn<bool (ProgramStateRef, const LocationContext *)> WantsRegionChangeUpdateFunc;
typedef CheckerFn<ProgramStateRef (ProgramStateRef,
const InvalidatedSymbols &Escaped,
Index: include/clang/StaticAnalyzer/Core/Checker.h
===================================================================
--- include/clang/StaticAnalyzer/Core/Checker.h
+++ include/clang/StaticAnalyzer/Core/Checker.h
@@ -321,14 +321,17 @@
const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> Explicits,
ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call) {
- return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
- Explicits, Regions, Call);
+ const CallEvent *Call,
+ const LocationContext *LCtx) {
+ return ((const CHECKER *) checker)->checkRegionChanges(state, invalidated,
+ Explicits, Regions,
+ Call, LCtx);
}
template <typename CHECKER>
static bool _wantsRegionChangeUpdate(void *checker,
- ProgramStateRef state) {
- return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
+ ProgramStateRef state,
+ const LocationContext *LCtx) {
+ return ((const CHECKER *) checker)->wantsRegionChangeUpdate(state, LCtx);
}
public:
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits