diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-01-20 00:47:45 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-01-20 00:47:45 +0000 |
commit | 7f5fce7200fdbf03f7d70134a57271e584fcb766 (patch) | |
tree | bac91a77f940d3ecc6e2d0bb9262754a990592dd /lib/Analysis/CheckDeadStores.cpp | |
parent | 06172d680766ffb96a22c48c390ec3e0fd41625b (diff) |
Dead stores checker: Fix <rdar://problem/6506065> by being more selective when say that a store is dead even though the computed value is used in the enclosing expression.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62552 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CheckDeadStores.cpp')
-rw-r--r-- | lib/Analysis/CheckDeadStores.cpp | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/lib/Analysis/CheckDeadStores.cpp b/lib/Analysis/CheckDeadStores.cpp index cad19f4f93..4f51cd8d9a 100644 --- a/lib/Analysis/CheckDeadStores.cpp +++ b/lib/Analysis/CheckDeadStores.cpp @@ -39,6 +39,9 @@ public: virtual ~DeadStoreObs() {} + bool isConsumedExpr(Expr* E) const; + + void Report(VarDecl* V, DeadStoreKind dsk, SourceLocation L, SourceRange R) { std::string name = V->getNameAsString(); @@ -145,10 +148,9 @@ public: return; // Otherwise, issue a warning. - DeadStoreKind dsk = - Parents.isSubExpr(B) - ? Enclosing - : (isIncrement(VD,B) ? DeadIncrement : Standard); + DeadStoreKind dsk = isConsumedExpr(B) + ? Enclosing + : (isIncrement(VD,B) ? DeadIncrement : Standard); CheckVarDecl(VD, DR, B->getRHS(), dsk, AD, Live); } @@ -161,7 +163,7 @@ public: // about preincrements to dead variables when the preincrement occurs // as a subexpression. This can lead to false negatives, e.g. "(++x);" // A generalized dead code checker should find such issues. - if (U->isPrefix() && Parents.isSubExpr(U)) + if (U->isPrefix() && isConsumedExpr(U)) return; Expr *Ex = U->getSubExpr()->IgnoreParenCasts(); @@ -203,6 +205,43 @@ public: } // end anonymous namespace +bool DeadStoreObs::isConsumedExpr(Expr* E) const { + Stmt *P = Parents.getParent(E); + Stmt *DirectChild = E; + + // Ignore parents that are parentheses or casts. + while (P && (isa<ParenExpr>(E) || isa<CastExpr>(E))) { + DirectChild = P; + P = Parents.getParent(P); + } + + if (!P) + return false; + + switch (P->getStmtClass()) { + default: + return isa<Expr>(P); + case Stmt::BinaryOperatorClass: { + BinaryOperator *BE = cast<BinaryOperator>(P); + return BE->getOpcode()==BinaryOperator::Comma && DirectChild==BE->getLHS(); + } + case Stmt::ForStmtClass: + return DirectChild == cast<ForStmt>(P)->getCond(); + case Stmt::WhileStmtClass: + return DirectChild == cast<WhileStmt>(P)->getCond(); + case Stmt::DoStmtClass: + return DirectChild == cast<DoStmt>(P)->getCond(); + case Stmt::IfStmtClass: + return DirectChild == cast<IfStmt>(P)->getCond(); + case Stmt::IndirectGotoStmtClass: + return DirectChild == cast<IndirectGotoStmt>(P)->getTarget(); + case Stmt::SwitchStmtClass: + return DirectChild == cast<SwitchStmt>(P)->getCond(); + case Stmt::ReturnStmtClass: + return true; + } +} + //===----------------------------------------------------------------------===// // Driver function to invoke the Dead-Stores checker on a CFG. //===----------------------------------------------------------------------===// |