From: Ted Kremenek Date: Mon, 10 Sep 2007 17:36:42 +0000 (+0000) Subject: Fixed LiveVariables to no longer track the liveness of function pointers X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c0576ca6c6ba136e583985041bd324b0acc38f40;p=clang Fixed LiveVariables to no longer track the liveness of function pointers that refer to direct function calls. Modified interface of LiveVariables to only track liveness of VarDecls. This cleans up a bunch of edge cases, and removed the bug just mentioned. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41797 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Analysis/DeadStores.cpp b/Analysis/DeadStores.cpp index 4073eccf60..e0922eede9 100644 --- a/Analysis/DeadStores.cpp +++ b/Analysis/DeadStores.cpp @@ -36,29 +36,28 @@ public: return; // Is this an assignment to a variable? - if (DeclRefExpr* DR = dyn_cast(B->getLHS())) { + if (DeclRefExpr* DR = dyn_cast(B->getLHS())) // Is the variable live? - if (!L.isLive(Live,DR->getDecl())) { + if (!L.isLive(Live,cast(DR->getDecl()))) { SourceRange R = B->getRHS()->getSourceRange(); PP.getDiagnostics().Report(DR->getSourceRange().Begin(), diag::warn_dead_store, 0, 0, &R,1); } - } } else if(DeclStmt* DS = dyn_cast(S)) { // Iterate through the decls. Warn if any of them (which have // initializers) are not live. - for (Decl* D = DS->getDecl() ; D != NULL ; D = D->getNextDeclarator()) - if (VarDecl* V = dyn_cast(D)) - if (Expr* E = V->getInit()) - if (!L.isLive(Live,D)) { - SourceRange R = E->getSourceRange(); - PP.getDiagnostics().Report(D->getLocation(), - diag::warn_dead_store, 0, 0, - &R,1); - } + for (VarDecl* V = cast(DS->getDecl()); V != NULL ; + V = cast(V->getNextDeclarator())) + if (Expr* E = V->getInit()) + if (!L.isLive(Live,V)) { + SourceRange R = E->getSourceRange(); + PP.getDiagnostics().Report(V->getLocation(), + diag::warn_dead_store, 0, 0, + &R,1); + } } } }; diff --git a/Analysis/LiveVariables.cpp b/Analysis/LiveVariables.cpp index 1d06c26af8..4324b3ec56 100644 --- a/Analysis/LiveVariables.cpp +++ b/Analysis/LiveVariables.cpp @@ -65,10 +65,12 @@ void RegisterDecls::RegisterDeclChain(Decl* D) { } void RegisterDecls::Register(Decl* D) { - LiveVariables::VPair& VP = L.getVarInfoMap()[const_cast(D)]; + if (VarDecl* V = dyn_cast(D)) { + LiveVariables::VPair& VP = L.getVarInfoMap()[V]; - VP.V.AliveBlocks.reserve(cfg.getNumBlockIDs()); - VP.Idx = L.getNumDecls()++; + VP.V.AliveBlocks.resize(cfg.getNumBlockIDs()); + VP.Idx = L.getNumDecls()++; + } } void RegisterDecls::RegisterUsedDecls() { @@ -135,7 +137,7 @@ public: void VisitDeclStmt(DeclStmt* DS); void VisitUnaryOperator(UnaryOperator* U); - unsigned getIdx(const Decl* D) { + unsigned getIdx(const VarDecl* D) { LiveVariables::VarInfoMap& V = L.getVarInfoMap(); LiveVariables::VarInfoMap::iterator I = V.find(D); assert (I != V.end()); @@ -144,7 +146,7 @@ public: bool ProcessBlock(const CFGBlock* B); llvm::BitVector* getBlockEntryLiveness(const CFGBlock* B); - LiveVariables::VarInfo& KillVar(Decl* D); + LiveVariables::VarInfo& KillVar(VarDecl* D); }; void LivenessTFuncs::VisitStmt(Stmt* S) { @@ -163,7 +165,8 @@ void LivenessTFuncs::VisitDeclRefExpr(DeclRefExpr* DR) { Observer->ObserveStmt(DR,L,Live); // Register a use of the variable. - Live.set(getIdx(DR->getDecl())); + if (VarDecl* V = dyn_cast(DR->getDecl())) + Live.set(getIdx(V)); } void LivenessTFuncs::VisitStmtExpr(StmtExpr* S) { @@ -205,7 +208,8 @@ void LivenessTFuncs::VisitUnaryOperator(UnaryOperator* U) { } else if (DeclRefExpr* DR = dyn_cast(S)) { // Treat the --/++/& operator as a kill. - LiveVariables::VarInfo& V = KillVar(DR->getDecl()); + LiveVariables::VarInfo& V = + KillVar(cast(DR->getDecl())); if (!blockPreviouslyProcessed) V.AddKill(CurrentStmt,DR); @@ -225,7 +229,7 @@ void LivenessTFuncs::VisitUnaryOperator(UnaryOperator* U) { } } -LiveVariables::VarInfo& LivenessTFuncs::KillVar(Decl* D) { +LiveVariables::VarInfo& LivenessTFuncs::KillVar(VarDecl* D) { LiveVariables::VarInfoMap::iterator I = L.getVarInfoMap().find(D); assert (I != L.getVarInfoMap().end() && @@ -247,7 +251,7 @@ void LivenessTFuncs::VisitAssign(BinaryOperator* B) { Stmt* LHS = B->getLHS(); if (DeclRefExpr* DR = dyn_cast(LHS)) { - LiveVariables::VarInfo& V = KillVar(DR->getDecl()); + LiveVariables::VarInfo& V = KillVar(cast(DR->getDecl())); // We only need to register kills once, so we check if this block // has been previously processed. @@ -272,7 +276,7 @@ void LivenessTFuncs::VisitDeclStmt(DeclStmt* DS) { // in the sense that the value is obliterated, so we do not register // DeclStmts as a "kill site" for a variable. for (Decl* D = DS->getDecl(); D != NULL ; D = D->getNextDeclarator()) - KillVar(D); + KillVar(cast(D)); } llvm::BitVector* LivenessTFuncs::getBlockEntryLiveness(const CFGBlock* B) { @@ -385,7 +389,7 @@ void LiveVariables::runOnBlock(const CFGBlock* B, // liveness queries // -bool LiveVariables::isLive(const CFGBlock* B, const Decl* D) const { +bool LiveVariables::isLive(const CFGBlock* B, const VarDecl* D) const { BlockLivenessMap::const_iterator I = LiveAtBlockEntryMap.find(B); assert (I != LiveAtBlockEntryMap.end()); @@ -395,13 +399,13 @@ bool LiveVariables::isLive(const CFGBlock* B, const Decl* D) const { return I->second[VI->second.Idx]; } -bool LiveVariables::isLive(llvm::BitVector& Live, const Decl* D) const { +bool LiveVariables::isLive(llvm::BitVector& Live, const VarDecl* D) const { VarInfoMap::const_iterator VI = VarInfos.find(D); assert (VI != VarInfos.end()); return Live[VI->second.Idx]; } -bool LiveVariables::KillsVar(const Stmt* S, const Decl* D) const { +bool LiveVariables::KillsVar(const Stmt* S, const VarDecl* D) const { VarInfoMap::const_iterator VI = VarInfos.find(D); assert (VI != VarInfos.end()); @@ -413,13 +417,13 @@ bool LiveVariables::KillsVar(const Stmt* S, const Decl* D) const { return false; } -LiveVariables::VarInfo& LiveVariables::getVarInfo(const Decl* D) { +LiveVariables::VarInfo& LiveVariables::getVarInfo(const VarDecl* D) { VarInfoMap::iterator VI = VarInfos.find(D); assert (VI != VarInfos.end()); return VI->second.V; } -const LiveVariables::VarInfo& LiveVariables::getVarInfo(const Decl* D) const { +const LiveVariables::VarInfo& LiveVariables::getVarInfo(const VarDecl* D) const{ return const_cast(this)->getVarInfo(D); } @@ -465,4 +469,44 @@ void LiveVariables::dumpBlockLiveness(SourceManager& M) const { dumpLiveness(I->second,M); } + + fprintf(stderr,"\n"); +} + +void LiveVariables::dumpVarLiveness(SourceManager& SM) const { + + for (VarInfoMap::iterator I = VarInfos.begin(), E=VarInfos.end(); I!=E; ++I) { + SourceLocation PhysLoc = SM.getPhysicalLoc(I->first->getLocation()); + + fprintf(stderr, "[ %s <%s:%u:%u> ]\n", + I->first->getIdentifier()->getName(), + SM.getSourceName(PhysLoc), + SM.getLineNumber(PhysLoc), + SM.getColumnNumber(PhysLoc)); + + I->second.V.Dump(SM); + } +} + +void LiveVariables::VarInfo::Dump(SourceManager& SM) const { + fprintf(stderr," Blocks Alive:"); + for (unsigned i = 0; i < AliveBlocks.size(); ++i) { + if (i % 5 == 0) + fprintf(stderr,"\n "); + + fprintf(stderr," B%d", i); + } + + fprintf(stderr,"\n Kill Sites:\n"); + for (KillsSet::const_iterator I = Kills.begin(), E = Kills.end(); I!=E; ++I) { + SourceLocation PhysLoc = + SM.getPhysicalLoc(I->second->getSourceRange().Begin()); + + fprintf(stderr, " <%s:%u:%u>\n", + SM.getSourceName(PhysLoc), + SM.getLineNumber(PhysLoc), + SM.getColumnNumber(PhysLoc)); + } + + fprintf(stderr,"\n"); } \ No newline at end of file diff --git a/Driver/ASTStreamers.cpp b/Driver/ASTStreamers.cpp index 59be1b36e7..d4c55ad681 100644 --- a/Driver/ASTStreamers.cpp +++ b/Driver/ASTStreamers.cpp @@ -240,7 +240,8 @@ namespace { virtual void VisitCFG(CFG& C) { LiveVariables L; L.runOnCFG(C); - L.dumpBlockLiveness(PP.getSourceManager()); + L.dumpBlockLiveness(PP.getSourceManager()); + L.dumpVarLiveness(PP.getSourceManager()); } }; } // end anonymous namespace diff --git a/include/clang/Analysis/LiveVariables.h b/include/clang/Analysis/LiveVariables.h index 18b6b18683..7d1d0210a0 100644 --- a/include/clang/Analysis/LiveVariables.h +++ b/include/clang/Analysis/LiveVariables.h @@ -22,7 +22,7 @@ namespace clang { class Stmt; class DeclRefExpr; - class Decl; + class VarDecl; class CFG; class CFGBlock; class SourceManager; @@ -45,7 +45,7 @@ public: /// then V contains the liveness information after the execution of /// the given block. virtual void ObserveBlockExit(const CFGBlock* B, LiveVariables& L, - llvm::BitVector& V); + llvm::BitVector& V); }; class LiveVariables { @@ -70,7 +70,10 @@ public: void AddKill(Stmt* S, DeclRefExpr* DR) { Kills.push_back(std::make_pair(const_cast(S), const_cast(DR))); - } + } + + // Dump - prints VarInfo data to stderr. + void Dump(SourceManager& M) const; }; struct VPair { @@ -78,7 +81,7 @@ public: unsigned Idx; }; - typedef llvm::DenseMap VarInfoMap; + typedef llvm::DenseMap VarInfoMap; typedef llvm::DenseMap BlockLivenessMap; public: @@ -96,22 +99,22 @@ public: /// KillsVar - Return true if the specified statement kills the /// specified variable. - bool KillsVar(const Stmt* S, const Decl* D) const; + bool KillsVar(const Stmt* S, const VarDecl* D) const; /// IsLive - Return true if a variable is live at beginning of a specified // block. - bool isLive(const CFGBlock* B, const Decl* D) const; + bool isLive(const CFGBlock* B, const VarDecl* D) const; /// IsLive - Return true if a variable is live according to the provided /// livness bitvector. This is typically used by classes that subclass /// LiveVariablesObserver. - bool isLive(llvm::BitVector& V, const Decl* D) const; + bool isLive(llvm::BitVector& V, const VarDecl* D) const; /// getVarInfo - Return the liveness information associated with a given /// variable. - VarInfo& getVarInfo(const Decl* D); + VarInfo& getVarInfo(const VarDecl* D); - const VarInfo& getVarInfo(const Decl* D) const; + const VarInfo& getVarInfo(const VarDecl* D) const; /// getVarInfoMap VarInfoMap& getVarInfoMap() { return VarInfos; } @@ -124,6 +127,9 @@ public: // dumpBlockLiveness void dumpBlockLiveness(SourceManager& M) const; + // dumpVarLiveness + void dumpVarLiveness(SourceManager& M) const; + // getLiveAtBlockEntryMap BlockLivenessMap& getLiveAtBlockEntryMap() { return LiveAtBlockEntryMap; }