コード例 #1
0
 virtual bool visit(const WorkListUnit &U) {
   ProgramPoint P = U.getNode()->getLocation();
   const CFGBlock *B = 0;
   if (Optional<StmtPoint> SP = P.getAs<StmtPoint>()) {
     B = CBM->getBlock(SP->getStmt());
   } else if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
     B = BE->getDst();
   } else if (Optional<BlockEntrance> BEnt = P.getAs<BlockEntrance>()) {
     B = BEnt->getBlock();
   } else if (Optional<BlockExit> BExit = P.getAs<BlockExit>()) {
     B = BExit->getBlock();
   }
   if (!B)
     return true;
   
   return B == TargetBlock || CRA.isReachable(B, TargetBlock);
 }
コード例 #2
0
 virtual bool visit(const WorkListUnit &U) {
   ProgramPoint P = U.getNode()->getLocation();
   const CFGBlock *B = 0;
   if (StmtPoint *SP = dyn_cast<StmtPoint>(&P)) {
     B = CBM->getBlock(SP->getStmt());
   }
   else if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
     B = BE->getDst();
   }
   else if (BlockEntrance *BEnt = dyn_cast<BlockEntrance>(&P)) {
     B = BEnt->getBlock();
   }
   else if (BlockExit *BExit = dyn_cast<BlockExit>(&P)) {
     B = BExit->getBlock();
   }
   if (!B)
     return true;
   
   return B == TargetBlock || CRA.isReachable(B, TargetBlock);
 }
コード例 #3
0
// Returns false if a path to this block was not completely analyzed, or true
// otherwise.
bool
IdempotentOperationChecker::pathWasCompletelyAnalyzed(AnalysisDeclContext *AC,
                                                      const CFGBlock *CB,
                                                      const CoreEngine &CE) {

  CFGReverseBlockReachabilityAnalysis *CRA = AC->getCFGReachablityAnalysis();
  
  // Test for reachability from any aborted blocks to this block
  typedef CoreEngine::BlocksExhausted::const_iterator ExhaustedIterator;
  for (ExhaustedIterator I = CE.blocks_exhausted_begin(),
      E = CE.blocks_exhausted_end(); I != E; ++I) {
    const BlockEdge &BE =  I->first;

    // The destination block on the BlockEdge is the first block that was not
    // analyzed. If we can reach this block from the aborted block, then this
    // block was not completely analyzed.
    //
    // Also explicitly check if the current block is the destination block.
    // While technically reachable, it means we aborted the analysis on
    // a path that included that block.
    const CFGBlock *destBlock = BE.getDst();
    if (destBlock == CB || CRA->isReachable(destBlock, CB))
      return false;
  }

  // Test for reachability from blocks we just gave up on.
  typedef CoreEngine::BlocksAborted::const_iterator AbortedIterator;
  for (AbortedIterator I = CE.blocks_aborted_begin(),
       E = CE.blocks_aborted_end(); I != E; ++I) {
    const CFGBlock *destBlock = I->first;
    if (destBlock == CB || CRA->isReachable(destBlock, CB))
      return false;
  }
  
  // For the items still on the worklist, see if they are in blocks that
  // can eventually reach 'CB'.
  class VisitWL : public WorkList::Visitor {
    const CFGStmtMap *CBM;
    const CFGBlock *TargetBlock;
    CFGReverseBlockReachabilityAnalysis &CRA;
  public:
    VisitWL(const CFGStmtMap *cbm, const CFGBlock *targetBlock,
            CFGReverseBlockReachabilityAnalysis &cra)
      : CBM(cbm), TargetBlock(targetBlock), CRA(cra) {}
    virtual bool visit(const WorkListUnit &U) {
      ProgramPoint P = U.getNode()->getLocation();
      const CFGBlock *B = 0;
      if (StmtPoint *SP = dyn_cast<StmtPoint>(&P)) {
        B = CBM->getBlock(SP->getStmt());
      }
      else if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
        B = BE->getDst();
      }
      else if (BlockEntrance *BEnt = dyn_cast<BlockEntrance>(&P)) {
        B = BEnt->getBlock();
      }
      else if (BlockExit *BExit = dyn_cast<BlockExit>(&P)) {
        B = BExit->getBlock();
      }
      if (!B)
        return true;
      
      return B == TargetBlock || CRA.isReachable(B, TargetBlock);
    }
  };
  VisitWL visitWL(AC->getCFGStmtMap(), CB, *CRA);
  // Were there any items in the worklist that could potentially reach
  // this block?
  if (CE.getWorkList()->visitItemsInWorkList(visitWL))
    return false;

  // Verify that this block is reachable from the entry block
  if (!CRA->isReachable(&AC->getCFG()->getEntry(), CB))
    return false;

  // If we get to this point, there is no connection to the entry block or an
  // aborted block. This path is unreachable and we can report the error.
  return true;
}