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:
Zhongxing Xu 2010-03-04 09:04:52 +00:00
parent 1a7ed5868b
commit 5cb8d9d40f
6 changed files with 27 additions and 0 deletions

View File

@ -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

View File

@ -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; }

View File

@ -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;

View File

@ -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);
}

View File

@ -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)

View File

@ -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();
}