Example #1
0
void FindUnreachableCode(AnalysisContext &AC, Callback &CB) {
  CFG *cfg = AC.getCFG();
  if (!cfg)
    return;

  // Scan for reachable blocks.
  llvm::BitVector reachable(cfg->getNumBlockIDs());
  unsigned numReachable = ScanReachableFromBlock(cfg->getEntry(), reachable);

    // If there are no unreachable blocks, we're done.
  if (numReachable == cfg->getNumBlockIDs())
    return;

  SourceRange R1, R2;

  llvm::SmallVector<ErrLoc, 24> lines;
  bool AddEHEdges = AC.getAddEHEdges();

  // First, give warnings for blocks with no predecessors, as they
  // can't be part of a loop.
  for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
    CFGBlock &b = **I;
    if (!reachable[b.getBlockID()]) {
      if (b.pred_empty()) {
        if (!AddEHEdges
        && dyn_cast_or_null<CXXTryStmt>(b.getTerminator().getStmt())) {
            // When not adding EH edges from calls, catch clauses
            // can otherwise seem dead.  Avoid noting them as dead.
          numReachable += ScanReachableFromBlock(b, reachable);
          continue;
        }
        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.
          reachable.set(b.getBlockID());
          ++numReachable;
          continue;
        }
        lines.push_back(ErrLoc(c, R1, R2));
          // Avoid excessive errors by marking everything reachable from here
        numReachable += ScanReachableFromBlock(b, reachable);
      }
    }
  }

  if (numReachable < cfg->getNumBlockIDs()) {
      // And then give warnings for the tops of loops.
    for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
      CFGBlock &b = **I;
      if (!reachable[b.getBlockID()])
          // Avoid excessive errors by marking everything reachable from here
        lines.push_back(ErrLoc(MarkLiveTop(&b, reachable,
                                         AC.getASTContext().getSourceManager()),
                               SourceRange(), SourceRange()));
    }
  }

  llvm::array_pod_sort(lines.begin(), lines.end(), LineCmp);

  for (llvm::SmallVectorImpl<ErrLoc>::iterator I=lines.begin(), E=lines.end();
       I != E; ++I)
    if (I->Loc.isValid())
      CB.HandleUnreachable(I->Loc, I->R1, I->R2);
}