From 55f988efeb08b84c2dd9e4c05990b88c81fe2b58 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Thu, 21 Jan 2010 17:21:23 +0000 Subject: [PATCH] Improve unreachable code warnings with respect to dead binary and unary operators. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94084 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/CFG.cpp | 3 ++- lib/Sema/SemaChecking.cpp | 26 ++++++++++++++++++++------ test/Sema/warn-unreachable.c | 14 ++++++++++---- test/SemaCXX/warn-unreachable.cpp | 9 ++++++++- 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(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(S); + R1 = UO->getSubExpr()->getSourceRange(); + return UO->getOperatorLoc(); } case Stmt::CXXTryStmtClass: { return cast(S)->getHandler(0)->getCatchLoc(); @@ -2104,7 +2115,8 @@ static SourceLocation MarkLiveTop(CFGBlock *e, llvm::BitVector &live, std::queue 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 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}} +} -- 2.40.0