forked from OSchip/llvm-project
When profiling Environment, also profile with AnalysisContext*, bacause
we now may have identical states with different analysis context. Set the right AnalysisContext in state when entering and leaving a callee. With both of the above changes, we can pass the test case. llvm-svn: 97724
This commit is contained in:
parent
1a7ed5868b
commit
5cb8d9d40f
|
@ -59,11 +59,13 @@ public:
|
|||
SVal GetSVal(const Stmt* Ex, ValueManager& ValMgr) const;
|
||||
|
||||
AnalysisContext &getAnalysisContext() const { return *ACtx; }
|
||||
void setAnalysisContext(AnalysisContext *ctx) { ACtx = ctx; }
|
||||
|
||||
/// Profile - Profile the contents of an Environment object for use
|
||||
/// in a FoldingSet.
|
||||
static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) {
|
||||
E->ExprBindings.Profile(ID);
|
||||
ID.AddPointer(E->ACtx);
|
||||
}
|
||||
|
||||
/// Profile - Used to profile the contents of this object for inclusion
|
||||
|
|
|
@ -115,6 +115,8 @@ public:
|
|||
return Env.getAnalysisContext();
|
||||
}
|
||||
|
||||
const GRState *setAnalysisContext(AnalysisContext *ctx) const;
|
||||
|
||||
/// getEnvironment - Return the environment associated with this state.
|
||||
/// The environment is the mapping from expressions to values.
|
||||
const Environment& getEnvironment() const { return Env; }
|
||||
|
|
|
@ -682,6 +682,7 @@ void GRCallExitNodeBuilder::GenerateNode(const GRState *state) {
|
|||
// Get the callee's location context.
|
||||
const StackFrameContext *LocCtx
|
||||
= cast<StackFrameContext>(Pred->getLocationContext());
|
||||
state = state->setAnalysisContext(LocCtx->getParent()->getAnalysisContext());
|
||||
|
||||
PostStmt Loc(LocCtx->getCallSite(), LocCtx->getParent());
|
||||
bool isNew;
|
||||
|
|
|
@ -1309,6 +1309,7 @@ void GRExprEngine::ProcessCallEnter(GRCallEnterNodeBuilder &B) {
|
|||
|
||||
const GRState *state = B.getState();
|
||||
state = getStoreManager().EnterStackFrame(state, LocCtx);
|
||||
state = state->setAnalysisContext(LocCtx->getAnalysisContext());
|
||||
|
||||
B.GenerateNode(state, LocCtx);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,12 @@ using namespace clang;
|
|||
// FIXME: Move this elsewhere.
|
||||
ConstraintManager::~ConstraintManager() {}
|
||||
|
||||
const GRState *GRState::setAnalysisContext(AnalysisContext *ctx) const {
|
||||
GRState NewState = *this;
|
||||
NewState.Env.setAnalysisContext(ctx);
|
||||
return StateMgr->getPersistentState(NewState);
|
||||
}
|
||||
|
||||
GRStateManager::~GRStateManager() {
|
||||
for (std::vector<GRState::Printer*>::iterator I=Printers.begin(),
|
||||
E=Printers.end(); I!=E; ++I)
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
|
||||
|
||||
|
||||
// Test when entering f1(), we set the right AnalysisContext to Environment.
|
||||
// Otherwise, block-level expr '1 && a' would not be block-level.
|
||||
int a;
|
||||
|
||||
void f1() {
|
||||
if (1 && a)
|
||||
return;
|
||||
}
|
||||
|
||||
void f2() {
|
||||
f1();
|
||||
}
|
Loading…
Reference in New Issue