From f96f16d9f529ec95c20b9a91405653554e9646d1 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 7 Apr 2009 05:25:24 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68504 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/CheckDeadStores.cpp | 42 +++++++++++++++++++++++++++++--- lib/Analysis/LiveVariables.cpp | 18 -------------- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/lib/Analysis/CheckDeadStores.cpp b/lib/Analysis/CheckDeadStores.cpp index f75a96471a..69433d6396 100644 --- a/lib/Analysis/CheckDeadStores.cpp +++ b/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 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 &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{ + CFG *cfg; +public: + FindEscaped(CFG *c) : cfg(c) {} + + CFG& getCFG() { return *cfg; } + + llvm::SmallPtrSet 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(E)) + if (VarDecl* VD = dyn_cast(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/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp index b8b0aaca18..b0eb37b065 100644 --- a/lib/Analysis/LiveVariables.cpp +++ b/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(E)) - if (VarDecl* VD = dyn_cast(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); -- 2.50.1