summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-04-07 05:25:24 +0000
committerTed Kremenek <kremenek@apple.com>2009-04-07 05:25:24 +0000
commit4d947facad65cb319a54f6ad1d1a878026dd0645 (patch)
tree3bbdb9df8f8233f3afcca226fbc6c9e6607d6c69 /clang/lib
parent33d840cc8f59083b8966a4b88ab330436aabe467 (diff)
downloadbcm5719-llvm-4d947facad65cb319a54f6ad1d1a878026dd0645.tar.gz
bcm5719-llvm-4d947facad65cb319a54f6ad1d1a878026dd0645.zip
Remove hack from LiveVariables analysis where variables whose address are taken
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. llvm-svn: 68504
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Analysis/CheckDeadStores.cpp42
-rw-r--r--clang/lib/Analysis/LiveVariables.cpp18
2 files changed, 38 insertions, 22 deletions
diff --git a/clang/lib/Analysis/CheckDeadStores.cpp b/clang/lib/Analysis/CheckDeadStores.cpp
index f75a96471a1..69433d6396a 100644
--- a/clang/lib/Analysis/CheckDeadStores.cpp
+++ b/clang/lib/Analysis/CheckDeadStores.cpp
@@ -17,9 +17,11 @@
#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);
}
diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp
index b8b0aaca184..b0eb37b0652 100644
--- a/clang/lib/Analysis/LiveVariables.cpp
+++ b/clang/lib/Analysis/LiveVariables.cpp
@@ -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);
OpenPOWER on IntegriCloud