]> granicus.if.org Git - clang/commitdiff
Analyzer Core: Adding support for user-defined symbol dependencies. (For example...
authorAnna Zaks <ganna@apple.com>
Thu, 11 Aug 2011 16:43:28 +0000 (16:43 +0000)
committerAnna Zaks <ganna@apple.com>
Thu, 11 Aug 2011 16:43:28 +0000 (16:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137309 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
lib/StaticAnalyzer/Core/SymbolManager.cpp

index 4fa294055a6f3a08c17b463ad4d79575d012afb1..dc3d15b25979a354a18417db1aa584c49a01cf57 100644 (file)
@@ -91,6 +91,7 @@ public:
 };
 
 typedef const SymbolData* SymbolRef;
+typedef llvm::SmallVector<SymbolRef, 1> SymbolRefSmallVectorTy;
 
 /// A symbol representing the value of a MemRegion.
 class SymbolRegionValue : public SymbolData {
@@ -357,8 +358,12 @@ public:
 
 class SymbolManager {
   typedef llvm::FoldingSet<SymExpr> DataSetTy;
+  typedef llvm::DenseMap<SymbolRef, SymbolRefSmallVectorTy> SymbolDependTy;
 
   DataSetTy DataSet;
+  /// Stores the extra dependencies between symbols: the data should be kept
+  /// alive as long as the key is live.
+  SymbolDependTy SymbolDependencies;
   unsigned SymbolCounter;
   llvm::BumpPtrAllocator& BPAlloc;
   BasicValueFactory &BV;
@@ -413,6 +418,16 @@ public:
     return SE->getType(Ctx);
   }
 
+  /// \brief Add artificial symbol dependency.
+  ///
+  /// The dependent symbol should stay alive as long as the primary is alive.
+  void addSymbolDependency(const SymbolRef Primary, const SymbolRef Dependent);
+
+  /// \brief Drop all user-added dependencies on the primary symbol.
+  void removeSymbolDependencies(const SymbolRef Primary);
+
+  const SymbolRefSmallVectorTy *getDependentSymbols(const SymbolRef Primary);
+
   ASTContext &getContext() { return Ctx; }
   BasicValueFactory &getBasicVals() { return BV; }
 };
@@ -495,6 +510,10 @@ public:
   /// \brief Set to the value of the symbolic store after
   /// StoreManager::removeDeadBindings has been called.
   void setReapedStore(StoreRef st) { reapedStore = st; }
+
+private:
+  /// Mark the symbols dependent on the input symbol as live.
+  void markDependentsLive(SymbolRef sym);
 };
 
 class SymbolVisitor {
index 6d90d19f9ed84e2b079aca006a364d9bc7003b42..b4a0d69c00877057df318034c33e42169f9047f0 100644 (file)
@@ -248,9 +248,36 @@ bool SymbolManager::canSymbolicate(QualType T) {
   return false;
 }
 
+void SymbolManager::addSymbolDependency(const SymbolRef Primary,
+                                        const SymbolRef Dependent) {
+  SymbolDependencies[Primary].push_back(Dependent);
+}
+
+void SymbolManager::removeSymbolDependencies(const SymbolRef Primary) {
+  SymbolDependencies.erase(Primary);
+}
+
+const SymbolRefSmallVectorTy *SymbolManager::getDependentSymbols(
+                                                     const SymbolRef Primary) {
+  SymbolDependTy::const_iterator I = SymbolDependencies.find(Primary);
+  if (I == SymbolDependencies.end())
+    return 0;
+  return &I->second;
+}
+
+void SymbolReaper::markDependentsLive(SymbolRef sym) {
+  if (const SymbolRefSmallVectorTy *Deps = SymMgr.getDependentSymbols(sym)) {
+    for (SymbolRefSmallVectorTy::const_iterator I = Deps->begin(),
+                                                E = Deps->end(); I != E; ++I) {
+      markLive(*I);
+    }
+  }
+}
+
 void SymbolReaper::markLive(SymbolRef sym) {
   TheLiving.insert(sym);
   TheDead.erase(sym);
+  markDependentsLive(sym);
 }
 
 void SymbolReaper::markLive(const MemRegion *region) {
@@ -299,8 +326,10 @@ bool SymbolReaper::isLiveRegion(const MemRegion *MR) {
 }
 
 bool SymbolReaper::isLive(SymbolRef sym) {
-  if (TheLiving.count(sym))
+  if (TheLiving.count(sym)) {
+    markDependentsLive(sym);
     return true;
+  }
 
   if (const SymbolDerived *derived = dyn_cast<SymbolDerived>(sym)) {
     if (isLive(derived->getParentSymbol())) {