diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/BugReporter.cpp | 57 | 
1 files changed, 41 insertions, 16 deletions
| diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index 829e7482ebe..96aa4886186 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -363,6 +363,7 @@ static const Stmt *getEnclosingParent(const Stmt *S, const ParentMap &PM) {    case Stmt::DoStmtClass:    case Stmt::WhileStmtClass:    case Stmt::ObjCForCollectionStmtClass: +  case Stmt::CXXForRangeStmtClass:      return Parent;    default:      break; @@ -404,6 +405,10 @@ getEnclosingStmtLocation(const Stmt *S, SourceManager &SMgr, const ParentMap &P,            return PathDiagnosticLocation(Parent, SMgr, LC);          else            return PathDiagnosticLocation(S, SMgr, LC); +      case Stmt::CXXForRangeStmtClass: +        if (cast<CXXForRangeStmt>(Parent)->getBody() == S) +          return PathDiagnosticLocation(S, SMgr, LC); +        break;        case Stmt::DoStmtClass:            return PathDiagnosticLocation(S, SMgr, LC);        case Stmt::ForStmtClass: @@ -1253,6 +1258,7 @@ static bool isLoop(const Stmt *Term) {      case Stmt::ForStmtClass:      case Stmt::WhileStmtClass:      case Stmt::ObjCForCollectionStmtClass: +    case Stmt::CXXForRangeStmtClass:        return true;      default:        // Note that we intentionally do not include do..while here. @@ -1302,6 +1308,15 @@ static const Stmt *getStmtBeforeCond(ParentMap &PM, const Stmt *Term,  static bool isInLoopBody(ParentMap &PM, const Stmt *S, const Stmt *Term) {    const Stmt *LoopBody = 0;    switch (Term->getStmtClass()) { +    case Stmt::CXXForRangeStmtClass: { +      const CXXForRangeStmt *FR = cast<CXXForRangeStmt>(Term); +      if (isContainedByStmt(PM, FR->getInc(), S)) +        return true; +      if (isContainedByStmt(PM, FR->getLoopVarStmt(), S)) +        return true; +      LoopBody = FR->getBody(); +      break; +    }      case Stmt::ForStmtClass: {        const ForStmt *FS = cast<ForStmt>(Term);        if (isContainedByStmt(PM, FS->getInc(), S)) @@ -1718,16 +1733,20 @@ GenerateAlternateExtensivePathDiagnostic(PathDiagnostic& PD,          // Are we jumping to the head of a loop?  Add a special diagnostic.          if (const Stmt *Loop = BE->getSrc()->getLoopTarget()) {            PathDiagnosticLocation L(Loop, SM, PDB.LC); -          const CompoundStmt *CS = NULL; +          const Stmt *Body = NULL;            if (const ForStmt *FS = dyn_cast<ForStmt>(Loop)) -            CS = dyn_cast<CompoundStmt>(FS->getBody()); +            Body = FS->getBody();            else if (const WhileStmt *WS = dyn_cast<WhileStmt>(Loop)) -            CS = dyn_cast<CompoundStmt>(WS->getBody()); +            Body = WS->getBody();            else if (const ObjCForCollectionStmt *OFS = -                   dyn_cast<ObjCForCollectionStmt>(Loop)) { -            CS = dyn_cast<CompoundStmt>(OFS->getBody()); +                     dyn_cast<ObjCForCollectionStmt>(Loop)) { +            Body = OFS->getBody(); +          } else if (const CXXForRangeStmt *FRS = +                       dyn_cast<CXXForRangeStmt>(Loop)) { +            Body = FRS->getBody();            } +          // do-while statements are explicitly excluded here            PathDiagnosticEventPiece *p =              new PathDiagnosticEventPiece(L, "Looping back to the head " @@ -1737,7 +1756,7 @@ GenerateAlternateExtensivePathDiagnostic(PathDiagnostic& PD,            addEdgeToPath(PD.getActivePath(), PrevLoc, p->getLocation(), PDB.LC);            PD.getActivePath().push_front(p); -          if (CS) { +          if (const CompoundStmt *CS = dyn_cast_or_null<CompoundStmt>(Body)) {              addEdgeToPath(PD.getActivePath(), PrevLoc,                            PathDiagnosticLocation::createEndBrace(CS, SM),                            PDB.LC); @@ -1871,16 +1890,22 @@ static bool isConditionForTerminator(const Stmt *S, const Stmt *Cond) {      }      case Stmt::ObjCForCollectionStmtClass:        return cast<ObjCForCollectionStmt>(S)->getElement() == Cond; +    case Stmt::CXXForRangeStmtClass: { +      const CXXForRangeStmt *FRS = cast<CXXForRangeStmt>(S); +      return FRS->getCond() == Cond || FRS->getRangeInit() == Cond; +    }      default:        return false;    }  }  static bool isIncrementOrInitInForLoop(const Stmt *S, const Stmt *FL) { -  const ForStmt *FS = dyn_cast<ForStmt>(FL); -  if (!FS) -    return false; -  return FS->getInc() == S || FS->getInit() == S; +  if (const ForStmt *FS = dyn_cast<ForStmt>(FL)) +    return FS->getInc() == S || FS->getInit() == S; +  if (const CXXForRangeStmt *FRS = dyn_cast<CXXForRangeStmt>(FL)) +    return FRS->getInc() == S || FRS->getRangeStmt() == S || +           FRS->getLoopVarStmt() || FRS->getRangeInit() == S; +  return false;  }  typedef llvm::DenseSet<const PathDiagnosticCallPiece *> @@ -1903,16 +1928,15 @@ static void addContextEdges(PathPieces &pieces, SourceManager &SM,        continue;      PathDiagnosticLocation SrcLoc = Piece->getStartLocation(); -    const Stmt *Src = getLocStmt(SrcLoc);      SmallVector<PathDiagnosticLocation, 4> SrcContexts; -    PathDiagnosticLocation NextSrcContext = -      getEnclosingStmtLocation(Src, SM, PM, LCtx, /*allowNested=*/true); -    const Stmt *InnerStmt = Src; +    PathDiagnosticLocation NextSrcContext = SrcLoc; +    const Stmt *InnerStmt = 0;      while (NextSrcContext.isValid() && NextSrcContext.asStmt() != InnerStmt) {        SrcContexts.push_back(NextSrcContext);        InnerStmt = NextSrcContext.asStmt(); -      NextSrcContext = getEnclosingStmtLocation(InnerStmt, SM, PM, LCtx, true); +      NextSrcContext = getEnclosingStmtLocation(InnerStmt, SM, PM, LCtx, +                                                /*allowNested=*/true);      }      // Repeatedly split the edge as necessary. @@ -2024,7 +2048,8 @@ static void simplifySimpleBranches(PathPieces &pieces) {      // We only perform this transformation for specific branch kinds.      // We don't want to do this for do..while, for example.      if (!(isa<ForStmt>(s1Start) || isa<WhileStmt>(s1Start) || -          isa<IfStmt>(s1Start) || isa<ObjCForCollectionStmt>(s1Start))) +          isa<IfStmt>(s1Start) || isa<ObjCForCollectionStmt>(s1Start) || +          isa<CXXForRangeStmt>(s1Start)))        continue;      // Is s1End the branch condition? | 

