[PATCH] D25660: [Analyzer] Checker for iterators dereferenced beyond their range.

Artem Dergachev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 9 10:26:03 PST 2016


NoQ added a comment.

A quick example of how a bug reporter visitor for this checker may look like - it needs to be expanded significantly but here's a start.

F2675703: report-999911.html <https://reviews.llvm.org/F2675703> <== example of how it looks.

See, for example, `MallocChecker` to understand the rest of the bureaucracy around bug reporter visitors.

  PathDiagnosticPiece *IteratorPastEndChecker::IteratorVisitor::VisitNode(
      const ExplodedNode *N, const ExplodedNode *PrevN,
      BugReporterContext &BRC, BugReport &BR) {
    if (!TrackedRegion)
      return nullptr;
  
    const Stmt *S = PathDiagnosticLocation::getStmt(N);
    if (!S)
      return nullptr;
  
    const LocationContext *LC = N->getLocationContext();
  
    PathDiagnosticLocation L = PathDiagnosticLocation::createBegin(
        S, BRC.getSourceManager(), N->getLocationContext());
  
    ProgramStateRef State = N->getState(),
                    PrevState = PrevN->getState();
  
    const IteratorPosition *Pos =
                               getIteratorPosition(State, TrackedRegion),
                           *PrevPos =
                               getIteratorPosition(PrevState, TrackedRegion);
  
    // Because we're tracking this region, it must be an interesting region.
    assert(Pos);
  
    if (Pos && !PrevPos) {
      // We didn't know the state of this iterator before, why do we know it now?
      // Maybe it was constructed from another iterator (state of which we knew).
      // FIXME: Handle more carryover cases.
      if (const auto *CE = dyn_cast<CXXConstructExpr>(S)) {
        if (CE->getConstructor()->isCopyOrMoveConstructor()) {
          if (State->getSVal(CE, LC).getAsRegion() == TrackedRegion) {
            if (const MemRegion *FromRegion =
                    State->getSVal(CE->getArg(0), LC).getAsRegion()) {
              assert(getIteratorPosition(State, FromRegion));
              // Because we traverse the ExplodedGraph from bottom to top,
              // this affects how we handle the events before copying.
              TrackedRegion = FromRegion;
              // FIXME: More sensible text.
              return new PathDiagnosticEventPiece(L, "Iterator state copied");
            }
          }
        }
      }
  
      // Or maybe it's a brand-new iterator.
      TrackedRegion = nullptr;
      // FIXME: More sensible text.
      return new PathDiagnosticEventPiece(L, "Begin tracking the iterator");
    }
    return nullptr;
  }


https://reviews.llvm.org/D25660





More information about the cfe-commits mailing list