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;
|
SVal GetSVal(const Stmt* Ex, ValueManager& ValMgr) const;
|
||||||
|
|
||||||
AnalysisContext &getAnalysisContext() const { return *ACtx; }
|
AnalysisContext &getAnalysisContext() const { return *ACtx; }
|
||||||
|
void setAnalysisContext(AnalysisContext *ctx) { ACtx = ctx; }
|
||||||
|
|
||||||
/// Profile - Profile the contents of an Environment object for use
|
/// Profile - Profile the contents of an Environment object for use
|
||||||
/// in a FoldingSet.
|
/// in a FoldingSet.
|
||||||
static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) {
|
static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) {
|
||||||
E->ExprBindings.Profile(ID);
|
E->ExprBindings.Profile(ID);
|
||||||
|
ID.AddPointer(E->ACtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Profile - Used to profile the contents of this object for inclusion
|
/// Profile - Used to profile the contents of this object for inclusion
|
||||||
|
|
|
@ -115,6 +115,8 @@ public:
|
||||||
return Env.getAnalysisContext();
|
return Env.getAnalysisContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GRState *setAnalysisContext(AnalysisContext *ctx) const;
|
||||||
|
|
||||||
/// getEnvironment - Return the environment associated with this state.
|
/// getEnvironment - Return the environment associated with this state.
|
||||||
/// The environment is the mapping from expressions to values.
|
/// The environment is the mapping from expressions to values.
|
||||||
const Environment& getEnvironment() const { return Env; }
|
const Environment& getEnvironment() const { return Env; }
|
||||||
|
|
|
@ -682,6 +682,7 @@ void GRCallExitNodeBuilder::GenerateNode(const GRState *state) {
|
||||||
// Get the callee's location context.
|
// Get the callee's location context.
|
||||||
const StackFrameContext *LocCtx
|
const StackFrameContext *LocCtx
|
||||||
= cast<StackFrameContext>(Pred->getLocationContext());
|
= cast<StackFrameContext>(Pred->getLocationContext());
|
||||||
|
state = state->setAnalysisContext(LocCtx->getParent()->getAnalysisContext());
|
||||||
|
|
||||||
PostStmt Loc(LocCtx->getCallSite(), LocCtx->getParent());
|
PostStmt Loc(LocCtx->getCallSite(), LocCtx->getParent());
|
||||||
bool isNew;
|
bool isNew;
|
||||||
|
|
|
@ -1309,6 +1309,7 @@ void GRExprEngine::ProcessCallEnter(GRCallEnterNodeBuilder &B) {
|
||||||
|
|
||||||
const GRState *state = B.getState();
|
const GRState *state = B.getState();
|
||||||
state = getStoreManager().EnterStackFrame(state, LocCtx);
|
state = getStoreManager().EnterStackFrame(state, LocCtx);
|
||||||
|
state = state->setAnalysisContext(LocCtx->getAnalysisContext());
|
||||||
|
|
||||||
B.GenerateNode(state, LocCtx);
|
B.GenerateNode(state, LocCtx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,12 @@ using namespace clang;
|
||||||
// FIXME: Move this elsewhere.
|
// FIXME: Move this elsewhere.
|
||||||
ConstraintManager::~ConstraintManager() {}
|
ConstraintManager::~ConstraintManager() {}
|
||||||
|
|
||||||
|
const GRState *GRState::setAnalysisContext(AnalysisContext *ctx) const {
|
||||||
|
GRState NewState = *this;
|
||||||
|
NewState.Env.setAnalysisContext(ctx);
|
||||||
|
return StateMgr->getPersistentState(NewState);
|
||||||
|
}
|
||||||
|
|
||||||
GRStateManager::~GRStateManager() {
|
GRStateManager::~GRStateManager() {
|
||||||
for (std::vector<GRState::Printer*>::iterator I=Printers.begin(),
|
for (std::vector<GRState::Printer*>::iterator I=Printers.begin(),
|
||||||
E=Printers.end(); I!=E; ++I)
|
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