summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2010-01-15 23:17:13 +0000
committerMike Stump <mrs@apple.com>2010-01-15 23:17:13 +0000
commitd4d6fb3374066fc08350d071c6637460e87c8517 (patch)
tree6c9f20841f2d0d24c96fbd80025be92c51a67ee2 /clang/lib/Sema
parenta7f7b17bc7eb80d6a554c32878830058fa45f0c1 (diff)
downloadbcm5719-llvm-d4d6fb3374066fc08350d071c6637460e87c8517.tar.gz
bcm5719-llvm-d4d6fb3374066fc08350d071c6637460e87c8517.zip
Refine location reporting for unreachable code warnings for comma expressions.
llvm-svn: 93574
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp57
1 files changed, 45 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0ccb8f2b1d5..d81e187bb30 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1328,14 +1328,47 @@ static void MarkLive(CFGBlock *e, llvm::BitVector &live) {
}
}
+static SourceLocation GetUnreachableLoc(CFGBlock &b) {
+ Stmt *S;
+ if (!b.empty())
+ S = b[0].getStmt();
+ else if (b.getTerminator())
+ S = b.getTerminator();
+ else
+ return SourceLocation();
+
+ switch (S->getStmtClass()) {
+ case Expr::BinaryOperatorClass: {
+ BinaryOperator *Op = cast<BinaryOperator>(S);
+ if (Op->getOpcode() == BinaryOperator::Comma) {
+ if (b.size() < 2) {
+ CFGBlock *n = &b;
+ while (1) {
+ if (n->getTerminator())
+ return n->getTerminator()->getLocStart();
+ if (n->succ_size() != 1)
+ return SourceLocation();
+ n = n[0].succ_begin()[0];
+ if (n->pred_size() != 1)
+ return SourceLocation();
+ if (!n->empty())
+ return n[0][0].getStmt()->getLocStart();
+ }
+ }
+ return b[1].getStmt()->getLocStart();
+ }
+ }
+ default: ;
+ }
+ return S->getLocStart();
+}
+
static SourceLocation MarkLiveTop(CFGBlock *e, llvm::BitVector &live,
SourceManager &SM) {
std::queue<CFGBlock*> workq;
// Prep work queue
workq.push(e);
- SourceLocation top;
- if (!e->empty())
- top = e[0][0].getStmt()->getLocStart();
+ SourceLocation top = GetUnreachableLoc(*e);
bool FromMainFile = false;
bool FromSystemHeader = false;
bool TopValid = false;
@@ -1348,11 +1381,7 @@ static SourceLocation MarkLiveTop(CFGBlock *e, llvm::BitVector &live,
while (!workq.empty()) {
CFGBlock *item = workq.front();
workq.pop();
- SourceLocation c;
- if (!item->empty())
- c = item[0][0].getStmt()->getLocStart();
- else if (item->getTerminator())
- c = item->getTerminator()->getLocStart();
+ SourceLocation c = GetUnreachableLoc(*item);
if (c.isValid()
&& (!TopValid
|| (SM.isFromMainFile(c) && !FromMainFile)
@@ -1412,10 +1441,14 @@ void Sema::CheckUnreachable(AnalysisContext &AC) {
CFGBlock &b = **I;
if (!live[b.getBlockID()]) {
if (b.pred_begin() == b.pred_end()) {
- if (!b.empty())
- lines.push_back(b[0].getStmt()->getLocStart());
- else if (b.getTerminator())
- lines.push_back(b.getTerminator()->getLocStart());
+ SourceLocation c = GetUnreachableLoc(b);
+ if (!c.isValid()) {
+ // Blocks without a location can't produce a warning, so don't mark
+ // reachable blocks from here as live.
+ live.set(b.getBlockID());
+ continue;
+ }
+ lines.push_back(c);
// Avoid excessive errors by marking everything reachable from here
MarkLive(&b, live);
}
OpenPOWER on IntegriCloud