]> granicus.if.org Git - clang/commitdiff
When profiling Environment, also profile with AnalysisContext*, bacause
authorZhongxing Xu <xuzhongxing@gmail.com>
Thu, 4 Mar 2010 09:04:52 +0000 (09:04 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Thu, 4 Mar 2010 09:04:52 +0000 (09:04 +0000)
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

include/clang/Checker/PathSensitive/Environment.h
include/clang/Checker/PathSensitive/GRState.h
lib/Checker/GRCoreEngine.cpp
lib/Checker/GRExprEngine.cpp
lib/Checker/GRState.cpp
test/Analysis/inline3.c [new file with mode: 0644]

index 0852c31faeb6f4e9678bfea757a3a557ef4e9ebc..e7c8319fb72bdfb30369f2dda1b60754a208cb2e 100644 (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
index 9194ee88a1a93a5b523b171cce23c87e7a017117..bc2fae57cfdd1739f39902c5513b721c752ce980 100644 (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; }
index a9347d01641c9195200684fb4353fcfdba952a49..63ac31d6064d4a8055df734c64741711bc64ad7f 100644 (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;
index ad229c7b8fbc85ca8834b0f845175213ac64c161..d25526e1ede24b4e2cb01fe214a44b7d9e5aa71e 100644 (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);
 }
index 592f930316e1717f7567ff80c76f1da07169c5ea..ce7d6e2a83888ca23c7d781aec5b403493766641 100644 (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)
diff --git a/test/Analysis/inline3.c b/test/Analysis/inline3.c
new file mode 100644 (file)
index 0000000..3661263
--- /dev/null
@@ -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();
+}