void Environment::print(raw_ostream &Out, const char *NL,
                        const char *Sep) const {
  bool isFirst = true;

  for (Environment::iterator I = begin(), E = end(); I != E; ++I) {
    const EnvironmentEntry &En = I.getKey();
    
    if (isFirst) {
      Out << NL << NL
          << "Expressions:"
          << NL;      
      isFirst = false;
    } else {
      Out << NL;
    }
    
    const Stmt *S = En.getStmt();
    
    Out << " (" << (const void*) En.getLocationContext() << ','
      << (const void*) S << ") ";
    LangOptions LO; // FIXME.
    S->printPretty(Out, 0, PrintingPolicy(LO));
    Out << " : " << I.getData();
  }
}
Exemple #2
0
Environment
EnvironmentManager::RemoveDeadBindings(Environment Env, const Stmt *S,
                                       SymbolReaper &SymReaper,
                                       const GRState *ST,
                              llvm::SmallVectorImpl<const MemRegion*> &DRoots) {

  CFG &C = *Env.getAnalysisContext().getCFG();

  // We construct a new Environment object entirely, as this is cheaper than
  // individually removing all the subexpression bindings (which will greatly
  // outnumber block-level expression bindings).
  Environment NewEnv = getInitialEnvironment(&Env.getAnalysisContext());

  // Iterate over the block-expr bindings.
  for (Environment::iterator I = Env.begin(), E = Env.end();
       I != E; ++I) {

    const Stmt *BlkExpr = I.getKey();

    // Not a block-level expression?
    if (!C.isBlkExpr(BlkExpr))
      continue;

    const SVal &X = I.getData();

    if (SymReaper.isLive(S, BlkExpr)) {
      // Copy the binding to the new map.
      NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);

      // If the block expr's value is a memory region, then mark that region.
      if (isa<loc::MemRegionVal>(X)) {
        const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
        DRoots.push_back(R);
        // Mark the super region of the RX as live.
        // e.g.: int x; char *y = (char*) &x; if (*y) ...
        // 'y' => element region. 'x' is its super region.
        // We only add one level super region for now.

        // FIXME: maybe multiple level of super regions should be added.
        if (const SubRegion *SR = dyn_cast<SubRegion>(R))
          DRoots.push_back(SR->getSuperRegion());
      }

      // Mark all symbols in the block expr's value live.
      MarkLiveCallback cb(SymReaper);
      ST->scanReachableSymbols(X, cb);
      continue;
    }

    // Otherwise the expression is dead with a couple exceptions.
    // Do not misclean LogicalExpr or ConditionalOperator.  It is dead at the
    // beginning of itself, but we need its UndefinedVal to determine its
    // SVal.
    if (X.isUndef() && cast<UndefinedVal>(X).getData())
      NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
  }

  return NewEnv;
}
Exemple #3
0
void GRState::print(llvm::raw_ostream& Out, const char* nl,
                    const char* sep) const {
  // Print the store.
  GRStateManager &Mgr = getStateManager();
  Mgr.getStoreManager().print(getStore(), Out, nl, sep);

  CFG &C = *getAnalysisContext().getCFG();

  // Print Subexpression bindings.
  bool isFirst = true;

  for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
    if (C.isBlkExpr(I.getKey()))
      continue;

    if (isFirst) {
      Out << nl << nl << "Sub-Expressions:" << nl;
      isFirst = false;
    }
    else { Out << nl; }

    Out << " (" << (void*) I.getKey() << ") ";
    LangOptions LO; // FIXME.
    I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
    Out << " : " << I.getData();
  }

  // Print block-expression bindings.
  isFirst = true;

  for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
    if (!C.isBlkExpr(I.getKey()))
      continue;

    if (isFirst) {
      Out << nl << nl << "Block-level Expressions:" << nl;
      isFirst = false;
    }
    else { Out << nl; }

    Out << " (" << (void*) I.getKey() << ") ";
    LangOptions LO; // FIXME.
    I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
    Out << " : " << I.getData();
  }

  Mgr.getConstraintManager().print(this, Out, nl, sep);

  // Print checker-specific data.
  for (std::vector<Printer*>::iterator I = Mgr.Printers.begin(),
                                       E = Mgr.Printers.end(); I != E; ++I) {
    (*I)->Print(Out, this, nl, sep);
  }
}
// removeDeadBindings:
//  - Remove subexpression bindings.
//  - Remove dead block expression bindings.
//  - Keep live block expression bindings:
//   - Mark their reachable symbols live in SymbolReaper,
//     see ScanReachableSymbols.
//   - Mark the region in DRoots if the binding is a loc::MemRegionVal.
Environment
EnvironmentManager::removeDeadBindings(Environment Env,
                                       SymbolReaper &SymReaper,
                                       ProgramStateRef ST) {

  // We construct a new Environment object entirely, as this is cheaper than
  // individually removing all the subexpression bindings (which will greatly
  // outnumber block-level expression bindings).
  Environment NewEnv = getInitialEnvironment();

  MarkLiveCallback CB(SymReaper);
  ScanReachableSymbols RSScaner(ST, CB);

  llvm::ImmutableMapRef<EnvironmentEntry,SVal>
    EBMapRef(NewEnv.ExprBindings.getRootWithoutRetain(),
             F.getTreeFactory());

  // Iterate over the block-expr bindings.
  for (Environment::iterator I = Env.begin(), E = Env.end();
       I != E; ++I) {

    const EnvironmentEntry &BlkExpr = I.getKey();
    const SVal &X = I.getData();

    if (SymReaper.isLive(BlkExpr.getStmt(), BlkExpr.getLocationContext())) {
      // Copy the binding to the new map.
      EBMapRef = EBMapRef.add(BlkExpr, X);

      // If the block expr's value is a memory region, then mark that region.
      if (Optional<loc::MemRegionVal> R = X.getAs<loc::MemRegionVal>())
        SymReaper.markLive(R->getRegion());

      // Mark all symbols in the block expr's value live.
      RSScaner.scan(X);
      continue;
    } else {
      SymExpr::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
      for (; SI != SE; ++SI)
        SymReaper.maybeDead(*SI);
    }
  }

  NewEnv.ExprBindings = EBMapRef.asImmutableMap();
  return NewEnv;
}
Exemple #5
0
void Environment::printAux(raw_ostream &Out, bool printLocations,
                           const char *NL,
                           const char *Sep) const{

  bool isFirst = true;

  for (Environment::iterator I = begin(), E = end(); I != E; ++I) {
    const EnvironmentEntry &En = I.getKey();
    if (IsLocation(En)) {
      if (!printLocations)
        continue;
    }
    else {
      if (printLocations)
        continue;
    }
    
    if (isFirst) {
      Out << NL << NL
          << (printLocations ? "Load/Store locations:" : "Expressions:")
          << NL;      
      isFirst = false;
    } else {
      Out << NL;
    }
    
    const Stmt *S = En.getStmt();
    if (printLocations) {
      S = (Stmt*) (((uintptr_t) S) & ((uintptr_t) ~0x1));
    }
    
    Out << " (" << (void*) En.getLocationContext() << ',' << (void*) S << ") ";
    LangOptions LO; // FIXME.
    S->printPretty(Out, 0, PrintingPolicy(LO));
    Out << " : " << I.getData();
  }
}
Exemple #6
0
// removeDeadBindings:
//  - Remove subexpression bindings.
//  - Remove dead block expression bindings.
//  - Keep live block expression bindings:
//   - Mark their reachable symbols live in SymbolReaper,
//     see ScanReachableSymbols.
//   - Mark the region in DRoots if the binding is a loc::MemRegionVal.
Environment
EnvironmentManager::removeDeadBindings(Environment Env,
                                       SymbolReaper &SymReaper,
                                       const ProgramState *ST) {

  // We construct a new Environment object entirely, as this is cheaper than
  // individually removing all the subexpression bindings (which will greatly
  // outnumber block-level expression bindings).
  Environment NewEnv = getInitialEnvironment();
  
  SmallVector<std::pair<EnvironmentEntry, SVal>, 10> deferredLocations;

  MarkLiveCallback CB(SymReaper);
  ScanReachableSymbols RSScaner(ST, CB);

  llvm::ImmutableMapRef<EnvironmentEntry,SVal>
    EBMapRef(NewEnv.ExprBindings.getRootWithoutRetain(),
             F.getTreeFactory());

  // Iterate over the block-expr bindings.
  for (Environment::iterator I = Env.begin(), E = Env.end();
       I != E; ++I) {

    const EnvironmentEntry &BlkExpr = I.getKey();
    // For recorded locations (used when evaluating loads and stores), we
    // consider them live only when their associated normal expression is
    // also live.
    // NOTE: This assumes that loads/stores that evaluated to UnknownVal
    // still have an entry in the map.
    if (IsLocation(BlkExpr)) {
      deferredLocations.push_back(std::make_pair(BlkExpr, I.getData()));
      continue;
    }
    const SVal &X = I.getData();

    if (SymReaper.isLive(BlkExpr.getStmt(), BlkExpr.getLocationContext())) {
      // Copy the binding to the new map.
      EBMapRef = EBMapRef.add(BlkExpr, X);

      // If the block expr's value is a memory region, then mark that region.
      if (isa<loc::MemRegionVal>(X)) {
        const MemRegion *R = cast<loc::MemRegionVal>(X).getRegion();
        SymReaper.markLive(R);
      }

      // Mark all symbols in the block expr's value live.
      RSScaner.scan(X);
      continue;
    }

    // Otherwise the expression is dead with a couple exceptions.
    // Do not misclean LogicalExpr or ConditionalOperator.  It is dead at the
    // beginning of itself, but we need its UndefinedVal to determine its
    // SVal.
    if (X.isUndef() && cast<UndefinedVal>(X).getData())
      EBMapRef = EBMapRef.add(BlkExpr, X);
  }
  
  // Go through he deferred locations and add them to the new environment if
  // the correspond Stmt* is in the map as well.
  for (SmallVectorImpl<std::pair<EnvironmentEntry, SVal> >::iterator
      I = deferredLocations.begin(), E = deferredLocations.end(); I != E; ++I) {
    const EnvironmentEntry &En = I->first;
    const Stmt *S = (Stmt*) (((uintptr_t) En.getStmt()) & (uintptr_t) ~0x1);
    if (EBMapRef.lookup(EnvironmentEntry(S, En.getLocationContext())))
      EBMapRef = EBMapRef.add(En, I->second);
  }

  NewEnv.ExprBindings = EBMapRef.asImmutableMap();
  return NewEnv;
}
Exemple #7
0
Environment
EnvironmentManager::RemoveDeadBindings(Environment Env,
                                       SymbolReaper &SymReaper,
                                       const GRState *ST,
                              llvm::SmallVectorImpl<const MemRegion*> &DRoots) {

  CFG &C = *SymReaper.getLocationContext()->getCFG();

  // We construct a new Environment object entirely, as this is cheaper than
  // individually removing all the subexpression bindings (which will greatly
  // outnumber block-level expression bindings).
  Environment NewEnv = getInitialEnvironment();

  // Iterate over the block-expr bindings.
  for (Environment::iterator I = Env.begin(), E = Env.end();
       I != E; ++I) {

    const Stmt *BlkExpr = I.getKey();
    const SVal &X = I.getData();

    // Block-level expressions in callers are assumed always live.
    if (isBlockExprInCallers(BlkExpr, SymReaper.getLocationContext())) {
      NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);

      if (isa<loc::MemRegionVal>(X)) {
        const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
        DRoots.push_back(R);
      }

      // Mark all symbols in the block expr's value live.
      MarkLiveCallback cb(SymReaper);
      ST->scanReachableSymbols(X, cb);
      continue;
    }

    // Not a block-level expression?
    if (!C.isBlkExpr(BlkExpr))
      continue;

    if (SymReaper.isLive(BlkExpr)) {
      // Copy the binding to the new map.
      NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);

      // If the block expr's value is a memory region, then mark that region.
      if (isa<loc::MemRegionVal>(X)) {
        const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
        DRoots.push_back(R);
      }

      // Mark all symbols in the block expr's value live.
      MarkLiveCallback cb(SymReaper);
      ST->scanReachableSymbols(X, cb);
      continue;
    }

    // Otherwise the expression is dead with a couple exceptions.
    // Do not misclean LogicalExpr or ConditionalOperator.  It is dead at the
    // beginning of itself, but we need its UndefinedVal to determine its
    // SVal.
    if (X.isUndef() && cast<UndefinedVal>(X).getData())
      NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
  }

  return NewEnv;
}
void ProgramState::print(raw_ostream &Out, CFG &C,
                         const char *NL, const char *Sep) const {
  // Print the store.
  ProgramStateManager &Mgr = getStateManager();
  Mgr.getStoreManager().print(getStore(), Out, NL, Sep);

  // Print Subexpression bindings.
  bool isFirst = true;

  // FIXME: All environment printing should be moved inside Environment.
  for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
    if (C.isBlkExpr(I.getKey()) || IsEnvLoc(I.getKey()))
      continue;

    if (isFirst) {
      Out << NL << NL << "Sub-Expressions:" << NL;
      isFirst = false;
    } else {
      Out << NL;
    }

    Out << " (" << (void*) I.getKey() << ") ";
    LangOptions LO; // FIXME.
    I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
    Out << " : " << I.getData();
  }

  // Print block-expression bindings.
  isFirst = true;

  for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
    if (!C.isBlkExpr(I.getKey()))
      continue;

    if (isFirst) {
      Out << NL << NL << "Block-level Expressions:" << NL;
      isFirst = false;
    } else {
      Out << NL;
    }

    Out << " (" << (void*) I.getKey() << ") ";
    LangOptions LO; // FIXME.
    I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
    Out << " : " << I.getData();
  }
  
  // Print locations.
  isFirst = true;
  
  for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
    if (!IsEnvLoc(I.getKey()))
      continue;
    
    if (isFirst) {
      Out << NL << NL << "Load/store locations:" << NL;
      isFirst = false;
    } else {
      Out << NL;
    }

    const Stmt *S = (Stmt*) (((uintptr_t) I.getKey()) & ((uintptr_t) ~0x1));
    
    Out << " (" << (void*) S << ") ";
    LangOptions LO; // FIXME.
    S->printPretty(Out, 0, PrintingPolicy(LO));
    Out << " : " << I.getData();
  }

  Mgr.getConstraintManager().print(this, Out, NL, Sep);

  // Print checker-specific data.
  Mgr.getOwningEngine()->printState(Out, this, NL, Sep);
}
Exemple #9
0
// removeDeadBindings:
//  - Remove subexpression bindings.
//  - Remove dead block expression bindings.
//  - Keep live block expression bindings:
//   - Mark their reachable symbols live in SymbolReaper,
//     see ScanReachableSymbols.
//   - Mark the region in DRoots if the binding is a loc::MemRegionVal.
Environment
EnvironmentManager::removeDeadBindings(Environment Env,
                                       SymbolReaper &SymReaper,
                                       const GRState *ST,
                              llvm::SmallVectorImpl<const MemRegion*> &DRoots) {

  CFG &C = *SymReaper.getLocationContext()->getCFG();

  // We construct a new Environment object entirely, as this is cheaper than
  // individually removing all the subexpression bindings (which will greatly
  // outnumber block-level expression bindings).
  Environment NewEnv = getInitialEnvironment();
  
  llvm::SmallVector<std::pair<const Stmt*, SVal>, 10> deferredLocations;

  // Iterate over the block-expr bindings.
  for (Environment::iterator I = Env.begin(), E = Env.end();
       I != E; ++I) {

    const Stmt *BlkExpr = I.getKey();
    
    // For recorded locations (used when evaluating loads and stores), we
    // consider them live only when their associated normal expression is
    // also live.
    // NOTE: This assumes that loads/stores that evaluated to UnknownVal
    // still have an entry in the map.
    if (IsLocation(BlkExpr)) {
      deferredLocations.push_back(std::make_pair(BlkExpr, I.getData()));
      continue;
    }
    
    const SVal &X = I.getData();

    // Block-level expressions in callers are assumed always live.
    if (isBlockExprInCallers(BlkExpr, SymReaper.getLocationContext())) {
      NewEnv.ExprBindings = F.add(NewEnv.ExprBindings, BlkExpr, X);

      if (isa<loc::MemRegionVal>(X)) {
        const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
        DRoots.push_back(R);
      }

      // Mark all symbols in the block expr's value live.
      MarkLiveCallback cb(SymReaper);
      ST->scanReachableSymbols(X, cb);
      continue;
    }

    // Not a block-level expression?
    if (!C.isBlkExpr(BlkExpr))
      continue;

    if (SymReaper.isLive(BlkExpr)) {
      // Copy the binding to the new map.
      NewEnv.ExprBindings = F.add(NewEnv.ExprBindings, BlkExpr, X);

      // If the block expr's value is a memory region, then mark that region.
      if (isa<loc::MemRegionVal>(X)) {
        const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
        DRoots.push_back(R);
      }

      // Mark all symbols in the block expr's value live.
      MarkLiveCallback cb(SymReaper);
      ST->scanReachableSymbols(X, cb);
      continue;
    }

    // Otherwise the expression is dead with a couple exceptions.
    // Do not misclean LogicalExpr or ConditionalOperator.  It is dead at the
    // beginning of itself, but we need its UndefinedVal to determine its
    // SVal.
    if (X.isUndef() && cast<UndefinedVal>(X).getData())
      NewEnv.ExprBindings = F.add(NewEnv.ExprBindings, BlkExpr, X);
  }
  
  // Go through he deferred locations and add them to the new environment if
  // the correspond Stmt* is in the map as well.
  for (llvm::SmallVectorImpl<std::pair<const Stmt*, SVal> >::iterator
      I = deferredLocations.begin(), E = deferredLocations.end(); I != E; ++I) {
    const Stmt *S = (Stmt*) (((uintptr_t) I->first) & (uintptr_t) ~0x1);
    if (NewEnv.ExprBindings.lookup(S))
      NewEnv.ExprBindings = F.add(NewEnv.ExprBindings, I->first, I->second);
  }

  return NewEnv;
}