示例#1
0
void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
                               ExplodedNodeSet &Dst) {
  
  // FIXME: static variables may have an initializer, but the second
  //  time a function is called those values may not be current.
  //  This may need to be reflected in the CFG.
  
  // Assumption: The CFG has one DeclStmt per Decl.
  const Decl *D = *DS->decl_begin();
  
  if (!D || !isa<VarDecl>(D)) {
    //TODO:AZ: remove explicit insertion after refactoring is done.
    Dst.insert(Pred);
    return;
  }
  
  // FIXME: all pre/post visits should eventually be handled by ::Visit().
  ExplodedNodeSet dstPreVisit;
  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
  
  StmtNodeBuilder B(dstPreVisit, Dst, *currentBuilderContext);
  const VarDecl *VD = dyn_cast<VarDecl>(D);
  for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
       I!=E; ++I) {
    ExplodedNode *N = *I;
    ProgramStateRef state = N->getState();
    
    // Decls without InitExpr are not initialized explicitly.
    const LocationContext *LC = N->getLocationContext();
    
    if (const Expr *InitEx = VD->getInit()) {
      SVal InitVal = state->getSVal(InitEx, LC);

      if (InitVal == state->getLValue(VD, LC) ||
          (VD->getType()->isArrayType() &&
           isa<CXXConstructExpr>(InitEx->IgnoreImplicit()))) {
        // We constructed the object directly in the variable.
        // No need to bind anything.
        B.generateNode(DS, N, state);
      } else {
        // We bound the temp obj region to the CXXConstructExpr. Now recover
        // the lazy compound value when the variable is not a reference.
        if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() && 
            !VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){
          InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion());
          assert(isa<nonloc::LazyCompoundVal>(InitVal));
        }
        
        // Recover some path-sensitivity if a scalar value evaluated to
        // UnknownVal.
        if (InitVal.isUnknown()) {
          QualType Ty = InitEx->getType();
          if (InitEx->isGLValue()) {
            Ty = getContext().getPointerType(Ty);
          }

          InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx, LC, Ty,
                                   currentBuilderContext->getCurrentBlockCount());
        }
        B.takeNodes(N);
        ExplodedNodeSet Dst2;
        evalBind(Dst2, DS, N, state->getLValue(VD, LC), InitVal, true);
        B.addNodes(Dst2);
      }
    }
    else {
      B.generateNode(DS, N,state->bindDeclWithNoInit(state->getRegion(VD, LC)));
    }
  }
}