From: Zhongxing Xu Date: Thu, 4 Mar 2010 09:04:52 +0000 (+0000) Subject: When profiling Environment, also profile with AnalysisContext*, bacause X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=57d3b76761bdba265769deb497afa784935602be;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97724 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Checker/PathSensitive/Environment.h b/include/clang/Checker/PathSensitive/Environment.h index 0852c31fae..e7c8319fb7 100644 --- a/include/clang/Checker/PathSensitive/Environment.h +++ b/include/clang/Checker/PathSensitive/Environment.h @@ -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 diff --git a/include/clang/Checker/PathSensitive/GRState.h b/include/clang/Checker/PathSensitive/GRState.h index 9194ee88a1..bc2fae57cf 100644 --- a/include/clang/Checker/PathSensitive/GRState.h +++ b/include/clang/Checker/PathSensitive/GRState.h @@ -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; } diff --git a/lib/Checker/GRCoreEngine.cpp b/lib/Checker/GRCoreEngine.cpp index a9347d0164..63ac31d606 100644 --- a/lib/Checker/GRCoreEngine.cpp +++ b/lib/Checker/GRCoreEngine.cpp @@ -682,6 +682,7 @@ void GRCallExitNodeBuilder::GenerateNode(const GRState *state) { // Get the callee's location context. const StackFrameContext *LocCtx = cast(Pred->getLocationContext()); + state = state->setAnalysisContext(LocCtx->getParent()->getAnalysisContext()); PostStmt Loc(LocCtx->getCallSite(), LocCtx->getParent()); bool isNew; diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index ad229c7b8f..d25526e1ed 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -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); } diff --git a/lib/Checker/GRState.cpp b/lib/Checker/GRState.cpp index 592f930316..ce7d6e2a83 100644 --- a/lib/Checker/GRState.cpp +++ b/lib/Checker/GRState.cpp @@ -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::iterator I=Printers.begin(), E=Printers.end(); I!=E; ++I) diff --git a/test/Analysis/inline3.c b/test/Analysis/inline3.c new file mode 100644 index 0000000000..3661263b6b --- /dev/null +++ b/test/Analysis/inline3.c @@ -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(); +}