diff options
| -rw-r--r-- | clang/lib/Analysis/CFG.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 26 | ||||
| -rw-r--r-- | clang/test/Sema/warn-unreachable.c | 14 | ||||
| -rw-r--r-- | clang/test/SemaCXX/warn-unreachable.cpp | 9 | 
4 files changed, 40 insertions, 12 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index ef3cdd88abe..5b8aeae5d1c 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/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/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 9a6f950c245..60134e2aa5f 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/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/clang/test/Sema/warn-unreachable.c b/clang/test/Sema/warn-unreachable.c index 205c39c6e2c..bbebebcc900 100644 --- a/clang/test/Sema/warn-unreachable.c +++ b/clang/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/clang/test/SemaCXX/warn-unreachable.cpp b/clang/test/SemaCXX/warn-unreachable.cpp index 13a82f4f183..a1f0dabec36 100644 --- a/clang/test/SemaCXX/warn-unreachable.cpp +++ b/clang/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}} +}  | 

