summaryrefslogtreecommitdiffstats
path: root/lib/Analysis/ReachableCode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/ReachableCode.cpp')
-rw-r--r--lib/Analysis/ReachableCode.cpp44
1 files changed, 28 insertions, 16 deletions
diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp
index 0543939..7afa586 100644
--- a/lib/Analysis/ReachableCode.cpp
+++ b/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);
OpenPOWER on IntegriCloud