Refine location reporting for unreachable code warnings for comma expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93574 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 0ccb8f2..d81e187 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1328,14 +1328,47 @@
}
}
+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 @@
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 @@
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);
}