Check if a region changes instead of look up if a region has bindings.

http://reviews.llvm.org/D5104

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
  include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  lib/StaticAnalyzer/Core/ProgramState.cpp
  lib/StaticAnalyzer/Core/SymbolManager.cpp
Index: include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -350,6 +350,9 @@
     return setDynamicTypeInfo(Reg, DynamicTypeInfo(NewTy, CanBeSubClassed));
   }
 
+  ProgramStateRef setDead(SymbolRef Sym) const;
+  bool isDead(SymbolRef Sym) const;
+
   //==---------------------------------------------------------------------==//
   // Accessing the Generic Data Map (GDM).
   //==---------------------------------------------------------------------==//
Index: include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -20,6 +20,7 @@
 #include "clang/Analysis/AnalysisContext.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/FoldingSet.h"
@@ -542,6 +543,8 @@
     return SE->getType();
   }
 
+  ProgramStateRef notifyBind(ProgramStateRef state, const MemRegion *MR);
+
   /// \brief Add artificial symbol dependency.
   ///
   /// The dependent symbol should stay alive as long as the primary is alive.
@@ -572,6 +575,7 @@
   
   const StackFrameContext *LCtx;
   const Stmt *Loc;
+  ProgramStateRef state;
   SymbolManager& SymMgr;
   StoreRef reapedStore;
   llvm::DenseMap<const MemRegion *, unsigned> includedRegionCache;
@@ -584,10 +588,8 @@
   /// considered live.
   /// If the stack frame context is NULL, everything on stack is considered
   /// dead.
-  SymbolReaper(const StackFrameContext *Ctx, const Stmt *s, SymbolManager& symmgr,
-               StoreManager &storeMgr)
-   : LCtx(Ctx), Loc(s), SymMgr(symmgr),
-     reapedStore(nullptr, storeMgr) {}
+  SymbolReaper(const StackFrameContext *Ctx, const Stmt *s,
+               ProgramStateRef currentState);
 
   ~SymbolReaper() {}
 
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -262,6 +262,8 @@
                                  ArrayRef<const MemRegion *> Explicits,
                                  ArrayRef<const MemRegion *> Regions,
                                  const CallEvent *Call) {
+  for (auto I = Regions.begin(), E = Regions.end(); I != E; I++)
+    state = getSymbolManager().notifyBind(state, *I);
   return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
                                                       Explicits, Regions, Call);
 }
@@ -357,7 +359,7 @@
   }
 
   const StackFrameContext *SFC = LC ? LC->getCurrentStackFrame() : nullptr;
-  SymbolReaper SymReaper(SFC, ReferenceStmt, SymMgr, getStoreManager());
+  SymbolReaper SymReaper(SFC, ReferenceStmt, CleanedState);
 
   getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper);
 
Index: lib/StaticAnalyzer/Core/ProgramState.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ProgramState.cpp
+++ lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -785,3 +785,16 @@
   assert(NewState);
   return NewState;
 }
+
+/// The GDM component containing symbols that were invalidated by direct
+/// binding to their regions
+REGISTER_TRAIT_WITH_PROGRAMSTATE(OverwrittenSymbols,
+                                 llvm::ImmutableSet<SymbolRef>)
+
+ProgramStateRef ProgramState::setDead(SymbolRef Sym) const {
+  return add<OverwrittenSymbols>(Sym);
+}
+
+bool ProgramState::isDead(SymbolRef Sym) const {
+  return contains<OverwrittenSymbols>(Sym);
+}
Index: lib/StaticAnalyzer/Core/SymbolManager.cpp
===================================================================
--- lib/StaticAnalyzer/Core/SymbolManager.cpp
+++ lib/StaticAnalyzer/Core/SymbolManager.cpp
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
@@ -304,6 +305,18 @@
   return cast<SymSymExpr>(data);
 }
 
+ProgramStateRef SymbolManager::notifyBind(ProgramStateRef state,
+                                          const MemRegion *MR) {
+  if (const TypedValueRegion* R = dyn_cast<TypedValueRegion>(MR)) {
+    llvm::FoldingSetNodeID profile;
+    SymbolRegionValue::Profile(profile, R);
+    void *InsertPos;
+    if (SymExpr *Sym = DataSet.FindNodeOrInsertPos(profile, InsertPos))
+      return state->setDead(Sym);
+  }
+  return state;
+}
+
 QualType SymbolConjured::getType() const {
   return T;
 }
@@ -365,6 +378,12 @@
   return I->second;
 }
 
+SymbolReaper::SymbolReaper(const StackFrameContext *Ctx, const Stmt *s,
+                           ProgramStateRef currentState)
+ : LCtx(Ctx), Loc(s), state(currentState), SymMgr(state->getSymbolManager()),
+   reapedStore(nullptr, state->getStateManager().getStoreManager()) {}
+
+
 void SymbolReaper::markDependentsLive(SymbolRef sym) {
   // Do not mark dependents more then once.
   SymbolMapTy::iterator LI = TheLiving.find(sym);
@@ -446,9 +465,11 @@
   bool KnownLive;
   
   switch (sym->getKind()) {
-  case SymExpr::RegionValueKind:
-    KnownLive = isLiveRegion(cast<SymbolRegionValue>(sym)->getRegion());
+  case SymExpr::RegionValueKind: {
+    const SymbolRegionValue *SRV = cast<SymbolRegionValue>(sym);
+    KnownLive = isLiveRegion(SRV->getRegion()) && !state->isDead(sym);
     break;
+  }
   case SymExpr::ConjuredKind:
     KnownLive = false;
     break;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to