aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Analysis/CFG.cpp3
-rw-r--r--lib/Sema/SemaChecking.cpp26
-rw-r--r--test/Sema/warn-unreachable.c14
-rw-r--r--test/SemaCXX/warn-unreachable.cpp9
4 files changed, 40 insertions, 12 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index ef3cdd88ab..5b8aeae5d1 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -237,7 +237,8 @@ static VariableArrayType* FindVA(Type* t) {
/// transferred to the caller. If CFG construction fails, this method returns
/// NULL.
CFG* CFGBuilder::buildCFG(const Decl *D, Stmt* Statement, ASTContext* C,
- bool AddEHEdges, bool AddScopes) {
+ bool addehedges, bool AddScopes) {
+ AddEHEdges = addehedges;
Context = C;
assert(cfg.get());
if (!Statement)
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 9a6f950c24..60134e2aa5 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -2064,7 +2064,8 @@ static unsigned MarkLive(CFGBlock *e, llvm::BitVector &live) {
return count;
}
-static SourceLocation GetUnreachableLoc(CFGBlock &b) {
+static SourceLocation GetUnreachableLoc(CFGBlock &b, SourceRange &R1,
+ SourceRange &R2) {
Stmt *S;
if (!b.empty())
S = b[0].getStmt();
@@ -2075,7 +2076,10 @@ static SourceLocation GetUnreachableLoc(CFGBlock &b) {
switch (S->getStmtClass()) {
case Expr::BinaryOperatorClass: {
- if (b.size() < 2) {
+ BinaryOperator *BO = cast<BinaryOperator>(S);
+ if (BO->getOpcode() == BinaryOperator::Comma) {
+ if (b.size() >= 2)
+ return b[1].getStmt()->getLocStart();
CFGBlock *n = &b;
while (1) {
if (n->getTerminator())
@@ -2089,7 +2093,14 @@ static SourceLocation GetUnreachableLoc(CFGBlock &b) {
return n[0][0].getStmt()->getLocStart();
}
}
- return b[1].getStmt()->getLocStart();
+ R1 = BO->getLHS()->getSourceRange();
+ R2 = BO->getRHS()->getSourceRange();
+ return BO->getOperatorLoc();
+ }
+ case Expr::UnaryOperatorClass: {
+ const UnaryOperator *UO = cast<UnaryOperator>(S);
+ R1 = UO->getSubExpr()->getSourceRange();
+ return UO->getOperatorLoc();
}
case Stmt::CXXTryStmtClass: {
return cast<CXXTryStmt>(S)->getHandler(0)->getCatchLoc();
@@ -2104,7 +2115,8 @@ static SourceLocation MarkLiveTop(CFGBlock *e, llvm::BitVector &live,
std::queue<CFGBlock*> workq;
// Prep work queue
workq.push(e);
- SourceLocation top = GetUnreachableLoc(*e);
+ SourceRange R1, R2;
+ SourceLocation top = GetUnreachableLoc(*e, R1, R2);
bool FromMainFile = false;
bool FromSystemHeader = false;
bool TopValid = false;
@@ -2117,7 +2129,7 @@ static SourceLocation MarkLiveTop(CFGBlock *e, llvm::BitVector &live,
while (!workq.empty()) {
CFGBlock *item = workq.front();
workq.pop();
- SourceLocation c = GetUnreachableLoc(*item);
+ SourceLocation c = GetUnreachableLoc(*item, R1, R2);
if (c.isValid()
&& (!TopValid
|| (SM.isFromMainFile(c) && !FromMainFile)
@@ -2169,6 +2181,8 @@ void Sema::CheckUnreachable(AnalysisContext &AC) {
// If there are no dead blocks, we're done.
return;
+ SourceRange R1, R2;
+
llvm::SmallVector<SourceLocation, 24> lines;
bool AddEHEdges = AC.getAddEHEdges();
// First, give warnings for blocks with no predecessors, as they
@@ -2184,7 +2198,7 @@ void Sema::CheckUnreachable(AnalysisContext &AC) {
count += MarkLive(&b, live);
continue;
}
- SourceLocation c = GetUnreachableLoc(b);
+ SourceLocation c = GetUnreachableLoc(b, R1, R2);
if (!c.isValid()) {
// Blocks without a location can't produce a warning, so don't mark
// reachable blocks from here as live.
diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c
index 205c39c6e2..bbebebcc90 100644
--- a/test/Sema/warn-unreachable.c
+++ b/test/Sema/warn-unreachable.c
@@ -30,14 +30,14 @@ void test2() {
dead(); // expected-warning {{will never be executed}}
case 2:
- live(),
- halt(),
+ live(), halt(),
dead(); // expected-warning {{will never be executed}}
case 3:
live()
- + halt();
- dead(); // expected-warning {{will never be executed}}
+ + // expected-warning {{will never be executed}}
+ halt();
+ dead();
case 4:
a4:
@@ -72,5 +72,11 @@ void test2() {
halt();
b6:
goto c6;
+ case 7:
+ halt()
+ + // expected-warning {{will never be executed}}
+ dead();
+ - // expected-warning {{will never be executed}}
+ halt();
}
}
diff --git a/test/SemaCXX/warn-unreachable.cpp b/test/SemaCXX/warn-unreachable.cpp
index 13a82f4f18..a1f0dabec3 100644
--- a/test/SemaCXX/warn-unreachable.cpp
+++ b/test/SemaCXX/warn-unreachable.cpp
@@ -1,6 +1,7 @@
// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code -Wno-unused-value
-int live();
+int &halt() __attribute__((noreturn));
+int &live();
int dead();
int liveti() throw(int);
int (*livetip)() throw(int);
@@ -33,3 +34,9 @@ void test2() {
throw 1;
dead(); // expected-warning {{will never be executed}}
}
+
+
+void test3() {
+ halt()
+ --; // expected-warning {{will never be executed}}
+}