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

    // Scan for reachable blocks from the entrance of the CFG.
    // If there are no unreachable blocks, we're done.
    llvm::BitVector reachable(cfg->getNumBlockIDs());
    unsigned numReachable = ScanReachableFromBlock(&cfg->getEntry(), reachable);
    if (numReachable == cfg->getNumBlockIDs())
        return;

    // If there aren't explicit EH edges, we should include the 'try' dispatch
    // blocks as roots.
    if (!AC.getCFGBuildOptions().AddEHEdges) {
        for (CFG::try_block_iterator I = cfg->try_blocks_begin(),
                E = cfg->try_blocks_end() ; I != E; ++I) {
            numReachable += ScanReachableFromBlock(*I, reachable);
        }
        if (numReachable == cfg->getNumBlockIDs())
            return;
    }

    // There are some unreachable blocks.  We need to find the root blocks that
    // contain code that should be considered unreachable.
    for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
        const CFGBlock *block = *I;
        // A block may have been marked reachable during this loop.
        if (reachable[block->getBlockID()])
            continue;

        DeadCodeScan DS(reachable);
        numReachable += DS.scanBackwards(block, CB);

        if (numReachable == cfg->getNumBlockIDs())
            return;
    }
}
Ejemplo n.º 2
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);
}