]> granicus.if.org Git - clang/commitdiff
Added initial boilerplate in GRExprEngine to allow checker-specific transfer
authorTed Kremenek <kremenek@apple.com>
Thu, 24 Apr 2008 18:31:42 +0000 (18:31 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 24 Apr 2008 18:31:42 +0000 (18:31 +0000)
function logic to act when symbols become dead.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50221 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/GRExprEngine.h
include/clang/Analysis/PathSensitive/ValueState.h
lib/Analysis/GRExprEngine.cpp
lib/Analysis/ValueState.cpp

index 2d088c788d63cad85bbd4573dcfe3ead112a1d49..819043edb4649afda6ae9dfbaaf57b1cb85b0e83 100644 (file)
@@ -53,6 +53,10 @@ protected:
   ///  Expr* in the CFG.  Used to prune out dead state.
   LiveVariables Liveness;
   
+  /// DeadSymbols - A scratch set used to record the set of symbols that
+  ///  were just marked dead by a call to ValueStateManager::RemoveDeadBindings.
+  ValueStateManager::DeadSymbolsTy DeadSymbols;
+  
   /// Builder - The current GRStmtNodeBuilder which is used when building the
   ///  nodes for a given statement.
   StmtNodeBuilder* Builder;
index 71e6abddba546ee8c97a6dcc5684033b81fa3309..5e287b23b022ffa61c09ae3bb566214058e4b0a9 100644 (file)
@@ -30,6 +30,7 @@
 #include "llvm/ADT/ImmutableMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Streams.h"
@@ -222,8 +223,11 @@ public:
   BasicValueFactory& getBasicValueFactory() { return BasicVals; }
   SymbolManager& getSymbolManager() { return SymMgr; }
   
+  typedef llvm::DenseSet<SymbolID> DeadSymbolsTy;
+  
   ValueState* RemoveDeadBindings(ValueState* St, Stmt* Loc, 
-                                 const LiveVariables& Liveness);
+                                 const LiveVariables& Liveness,
+                                 DeadSymbolsTy& DeadSymbols);
   
   ValueState* RemoveSubExprBindings(ValueState* St) {
     ValueState NewSt = *St;
index a6d8ef9051714e6f0297b1e1bffcf3058094db44..a287e542981efa749a3c908edb8d3c69c571e89b 100644 (file)
@@ -188,13 +188,34 @@ void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
   // Create the cleaned state.
   
   CleanedState = StateMgr.RemoveDeadBindings(StmtEntryNode->getState(),
-                                             CurrentStmt, Liveness);
+                                             CurrentStmt, Liveness,
+                                             DeadSymbols);
   
-  Builder->SetCleanedState(CleanedState);
+  // Process any special transfer function for dead symbols.
   
-  // Visit the statement.
+  NodeSet Tmp;
   
-  Visit(S, StmtEntryNode, Dst);
+  if (DeadSymbols.empty())
+    Tmp.Add(StmtEntryNode);
+  else {
+    SaveAndRestore<bool> OldSink(Builder->BuildSinks);
+/*      
+    FIXME: Will hook this up next.
+    TF->EvalDeadSymbols(Tmp, *this, *Builder, StmtEntryNode->getLocation(), Pred,
+                        CleanedState, DeadSymbols);
+*/
+    if (!Builder->BuildSinks && Tmp.empty() && !Builder->HasGeneratedNode)
+      Tmp.Add(StmtEntryNode);
+  }
+      
+  for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+    // Set the cleaned state.  
+    Builder->SetCleanedState(*I == StmtEntryNode ? CleanedState : (*I)->getState());
+  
+    // Visit the statement.  
+    Visit(S, StmtEntryNode, Dst);
+  }
   
   // If no nodes were generated, generate a new node that has all the
   // dead mappings removed.
index 8027ce9fcba1e30e816a030fc890064aa3cc2b1a..ed6a86075b136913d7499032a286ce01f465b84a 100644 (file)
@@ -32,7 +32,8 @@ const llvm::APSInt* ValueState::getSymVal(SymbolID sym) const {
 
 ValueState*
 ValueStateManager::RemoveDeadBindings(ValueState* St, Stmt* Loc,
-                                      const LiveVariables& Liveness) {  
+                                      const LiveVariables& Liveness,
+                                      DeadSymbolsTy& DeadSymbols) {  
   
   // This code essentially performs a "mark-and-sweep" of the VariableBindings.
   // The roots are any Block-level exprs and Decls that our liveness algorithm
@@ -133,13 +134,28 @@ ValueStateManager::RemoveDeadBindings(ValueState* St, Stmt* Loc,
       NewSt.VarBindings = Remove(NewSt, I.getKey());
   
   // Remove dead symbols.
-  for (ValueState::ce_iterator I = St->ce_begin(), E=St->ce_end(); I!=E; ++I)
-    if (!MarkedSymbols.count(I.getKey()))
-      NewSt.ConstEq = CEFactory.Remove(NewSt.ConstEq, I.getKey());
   
-  for (ValueState::cne_iterator I = St->cne_begin(), E=St->cne_end(); I!=E; ++I)
-    if (!MarkedSymbols.count(I.getKey()))
-      NewSt.ConstNotEq = CNEFactory.Remove(NewSt.ConstNotEq, I.getKey());
+  DeadSymbols.clear();
+  
+  for (ValueState::ce_iterator I = St->ce_begin(), E=St->ce_end(); I!=E; ++I) {
+
+    SymbolID sym = I.getKey();    
+    
+    if (!MarkedSymbols.count(sym)) {
+      DeadSymbols.insert(sym);
+      NewSt.ConstEq = CEFactory.Remove(NewSt.ConstEq, sym);
+    }
+  }
+  
+  for (ValueState::cne_iterator I = St->cne_begin(), E=St->cne_end(); I!=E;++I){
+    
+    SymbolID sym = I.getKey();
+    
+    if (!MarkedSymbols.count(sym)) {
+      DeadSymbols.insert(sym);
+      NewSt.ConstNotEq = CNEFactory.Remove(NewSt.ConstNotEq, sym);
+    }
+  }
   
   return getPersistentState(NewSt);
 }