]> granicus.if.org Git - clang/commitdiff
Remove hack from LiveVariables analysis where variables whose address are taken
authorTed Kremenek <kremenek@apple.com>
Tue, 7 Apr 2009 05:25:24 +0000 (05:25 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 7 Apr 2009 05:25:24 +0000 (05:25 +0000)
are considered 'live'. This hack isn't needed anymore because we have a
separation in the path-sensitive analyzer between variable names and bindings;
the analyzer can continue to reason about the storage of a variable after its
name is no longer directly referenced.  Now the live variables analysis literally means "is this name live".

Along this line, update the dead stores checker to explicitly look for variables
whose values have escaped.

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

lib/Analysis/CheckDeadStores.cpp
lib/Analysis/LiveVariables.cpp

index f75a96471a188dc48da2dcf5100de42e73986add..69433d6396a5b81fdcff37ee2288e0ad590329a0 100644 (file)
 #include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
 #include "clang/Analysis/PathSensitive/BugReporter.h"
 #include "clang/Analysis/PathSensitive/GRExprEngine.h"
+#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ParentMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/Compiler.h"
 
 using namespace clang;
@@ -30,16 +32,20 @@ class VISIBILITY_HIDDEN DeadStoreObs : public LiveVariables::ObserverTy {
   ASTContext &Ctx;
   BugReporter& BR;
   ParentMap& Parents;
+  llvm::SmallPtrSet<VarDecl*, 20> Escaped;
   
   enum DeadStoreKind { Standard, Enclosing, DeadIncrement, DeadInit };
     
 public:
-  DeadStoreObs(ASTContext &ctx, BugReporter& br, ParentMap& parents)
-    : Ctx(ctx), BR(br), Parents(parents) {}
+  DeadStoreObs(ASTContext &ctx, BugReporter& br, ParentMap& parents,
+               llvm::SmallPtrSet<VarDecl*, 20> &escaped)
+    : Ctx(ctx), BR(br), Parents(parents), Escaped(escaped) {}
   
   virtual ~DeadStoreObs() {}
 
   void Report(VarDecl* V, DeadStoreKind dsk, SourceLocation L, SourceRange R) {
+    if (Escaped.count(V))
+      return;
 
     std::string name = V->getNameAsString();
     
@@ -219,7 +225,35 @@ public:
 // Driver function to invoke the Dead-Stores checker on a CFG.
 //===----------------------------------------------------------------------===//
 
-void clang::CheckDeadStores(LiveVariables& L, BugReporter& BR) {  
-  DeadStoreObs A(BR.getContext(), BR, BR.getParentMap());
+namespace {
+class VISIBILITY_HIDDEN FindEscaped : public CFGRecStmtDeclVisitor<FindEscaped>{
+  CFG *cfg;
+public:
+  FindEscaped(CFG *c) : cfg(c) {}
+  
+  CFG& getCFG() { return *cfg; }
+  
+  llvm::SmallPtrSet<VarDecl*, 20> Escaped;
+
+  void VisitUnaryOperator(UnaryOperator* U) {
+    // Check for '&'.  Any VarDecl whose value has its address-taken we
+    // treat as escaped.
+    Expr* E = U->getSubExpr()->IgnoreParenCasts();
+    if (U->getOpcode() == UnaryOperator::AddrOf)
+      if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E))
+        if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) {
+          Escaped.insert(VD);
+          return;
+        }
+    Visit(E);
+  }
+};
+} // end anonymous namespace
+  
+
+void clang::CheckDeadStores(LiveVariables& L, BugReporter& BR) {
+  FindEscaped FS(BR.getCFG());
+  FS.getCFG().VisitBlockStmts(FS);  
+  DeadStoreObs A(BR.getContext(), BR, BR.getParentMap(), FS.Escaped);
   L.runOnAllBlocks(*BR.getCFG(), &A);
 }
index b8b0aaca18429d623c61c54e5376a79797c84e28..b0eb37b06524470a1fc8a7a3c4f700659799d185 100644 (file)
@@ -74,28 +74,10 @@ public:
       AlwaysLive.push_back(VD);    
   }
   
-  void VisitUnaryOperator(UnaryOperator* U) {
-    // Check for '&'.  Any VarDecl whose value has its address-taken we
-    // treat as always being live (flow-insensitive).
-
-    Expr* E = U->getSubExpr()->IgnoreParenCasts();
-    
-    if (U->getOpcode() == UnaryOperator::AddrOf)
-      if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E))
-        if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) {
-          AD.Register(VD);
-          AlwaysLive.push_back(VD);
-          return;
-        }
-      
-    Visit(E);
-  }
-    
   CFG& getCFG() { return AD.getCFG(); }
 };
 } // end anonymous namespace
 
-
 LiveVariables::LiveVariables(ASTContext& Ctx, CFG& cfg) {
   // Register all referenced VarDecls.
   getAnalysisData().setCFG(cfg);