diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Analysis/ReachableCode.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Analysis/ReachableCode.cpp | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/contrib/llvm/tools/clang/lib/Analysis/ReachableCode.cpp b/contrib/llvm/tools/clang/lib/Analysis/ReachableCode.cpp index 0543939..7afa586 100644 --- a/contrib/llvm/tools/clang/lib/Analysis/ReachableCode.cpp +++ b/contrib/llvm/tools/clang/lib/Analysis/ReachableCode.cpp @@ -30,20 +30,26 @@ static SourceLocation GetUnreachableLoc(const CFGBlock &b, SourceRange &R1, unsigned sn = 0; R1 = R2 = SourceRange(); -top: - if (sn < b.size()) - S = b[sn].getStmt(); - else if (b.getTerminator()) + if (sn < b.size()) { + CFGStmt CS = b[sn].getAs<CFGStmt>(); + if (!CS) + return SourceLocation(); + + S = CS.getStmt(); + } else if (b.getTerminator()) S = b.getTerminator(); else return SourceLocation(); + if (const Expr *Ex = dyn_cast<Expr>(S)) + S = Ex->IgnoreParenImpCasts(); + switch (S->getStmtClass()) { case Expr::BinaryOperatorClass: { const BinaryOperator *BO = cast<BinaryOperator>(S); if (BO->getOpcode() == BO_Comma) { if (sn+1 < b.size()) - return b[sn+1].getStmt()->getLocStart(); + return b[sn+1].getAs<CFGStmt>().getStmt()->getLocStart(); const CFGBlock *n = &b; while (1) { if (n->getTerminator()) @@ -54,7 +60,7 @@ top: if (n->pred_size() != 1) return SourceLocation(); if (!n->empty()) - return n[0][0].getStmt()->getLocStart(); + return n[0][0].getAs<CFGStmt>().getStmt()->getLocStart(); } } R1 = BO->getLHS()->getSourceRange(); @@ -72,8 +78,10 @@ top: R2 = CAO->getRHS()->getSourceRange(); return CAO->getOperatorLoc(); } + case Expr::BinaryConditionalOperatorClass: case Expr::ConditionalOperatorClass: { - const ConditionalOperator *CO = cast<ConditionalOperator>(S); + const AbstractConditionalOperator *CO = + cast<AbstractConditionalOperator>(S); return CO->getQuestionLoc(); } case Expr::MemberExprClass: { @@ -97,9 +105,6 @@ top: R1 = CE->getSubExpr()->getSourceRange(); return CE->getTypeBeginLoc(); } - case Expr::ImplicitCastExprClass: - ++sn; - goto top; case Stmt::CXXTryStmtClass: { return cast<CXXTryStmt>(S)->getHandler(0)->getCatchLoc(); } @@ -131,6 +136,9 @@ static SourceLocation MarkLiveTop(const CFGBlock *Start, } // Solve + CFGBlock::FilterOptions FO; + FO.IgnoreDefaultsWithCoveredEnums = 1; + while (!WL.empty()) { const CFGBlock *item = WL.back(); WL.pop_back(); @@ -147,8 +155,8 @@ static SourceLocation MarkLiveTop(const CFGBlock *Start, } reachable.set(item->getBlockID()); - for (CFGBlock::const_succ_iterator I=item->succ_begin(), E=item->succ_end(); - I != E; ++I) + for (CFGBlock::filtered_succ_iterator I = + item->filtered_succ_start_end(FO); I.hasMore(); ++I) if (const CFGBlock *B = *I) { unsigned blockID = B->getBlockID(); if (!reachable[blockID]) { @@ -190,14 +198,17 @@ unsigned ScanReachableFromBlock(const CFGBlock &Start, ++count; WL.push_back(&Start); - // Find the reachable blocks from 'Start'. + // Find the reachable blocks from 'Start'. + CFGBlock::FilterOptions FO; + FO.IgnoreDefaultsWithCoveredEnums = 1; + while (!WL.empty()) { const CFGBlock *item = WL.back(); WL.pop_back(); // Look at the successors and mark then reachable. - for (CFGBlock::const_succ_iterator I=item->succ_begin(), E=item->succ_end(); - I != E; ++I) + for (CFGBlock::filtered_succ_iterator I= item->filtered_succ_start_end(FO); + I.hasMore(); ++I) if (const CFGBlock *B = *I) { unsigned blockID = B->getBlockID(); if (!Reachable[blockID]) { @@ -234,7 +245,8 @@ void FindUnreachableCode(AnalysisContext &AC, Callback &CB) { CFGBlock &b = **I; if (!reachable[b.getBlockID()]) { if (b.pred_empty()) { - if (!AddEHEdges && dyn_cast_or_null<CXXTryStmt>(b.getTerminator())) { + if (!AddEHEdges + && dyn_cast_or_null<CXXTryStmt>(b.getTerminator().getStmt())) { // When not adding EH edges from calls, catch clauses // can otherwise seem dead. Avoid noting them as dead. numReachable += ScanReachableFromBlock(b, reachable); |