当前位置: 首页>>代码示例>>C++>>正文


C++ ExplodedNodeSet类代码示例

本文整理汇总了C++中ExplodedNodeSet的典型用法代码示例。如果您正苦于以下问题:C++ ExplodedNodeSet类的具体用法?C++ ExplodedNodeSet怎么用?C++ ExplodedNodeSet使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了ExplodedNodeSet类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: removeDeadOnEndOfSubprogram

void ExprEngine::removeDeadOnEndOfSubprogram(NodeBuilderContext& BC,
                                           ExplodedNode *Pred,
                                           ExplodedNodeSet &Dst) {
  // Find the last statement in the function and the corresponding basic block.
  const Stmt *LastSt = 0;
  const CFGBlock *Blk = 0;
  llvm::tie(LastSt, Blk) = getLastStmt(Pred);
  if (!Blk || !LastSt) {
    Dst.Add(Pred);
    return;
  }

  // Here, we destroy the current location context. We use the current
  // function's entire body as a diagnostic statement, with which the program
  // point will be associated. However, we only want to use LastStmt as a
  // reference for what to clean up if it's a ReturnStmt; otherwise, everything
  // is dead.
  SaveAndRestore<const NodeBuilderContext *> NodeContextRAII(currBldrCtx, &BC);
  const LocationContext *LCtx = Pred->getLocationContext();
  removeDead(Pred, Dst, dyn_cast<ReturnStmt>(LastSt), LCtx,
             LCtx->getAnalysisDeclContext()->getBody(),
             ProgramPoint::PostStmtPurgeDeadSymbolsKind);
}
开发者ID:gwelymernans,项目名称:lfort,代码行数:23,代码来源:ExprEngineCallAndReturn.cpp

示例2: getCheckerManager

void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
                               ExplodedNodeSet &Dst) {
  // Assumption: The CFG has one DeclStmt per Decl.
  const VarDecl *VD = dyn_cast_or_null<VarDecl>(*DS->decl_begin());

  if (!VD) {
    //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, *currBldrCtx);
  for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
       I!=E; ++I) {
    ExplodedNode *N = *I;
    ProgramStateRef state = N->getState();
    const LocationContext *LC = N->getLocationContext();

    // Decls without InitExpr are not initialized explicitly.
    if (const Expr *InitEx = VD->getInit()) {

      // Note in the state that the initialization has occurred.
      ExplodedNode *UpdatedN = N;
      SVal InitVal = state->getSVal(InitEx, LC);

      if (isa<CXXConstructExpr>(InitEx->IgnoreImplicit())) {
        // We constructed the object directly in the variable.
        // No need to bind anything.
        B.generateNode(DS, UpdatedN, 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()) {
          if (Optional<loc::MemRegionVal> M =
                  InitVal.getAs<loc::MemRegionVal>()) {
            InitVal = state->getSVal(M->getRegion());
            assert(InitVal.getAs<nonloc::LazyCompoundVal>());
          }
        }
        
        // 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.conjureSymbolVal(0, InitEx, LC, Ty,
                                                 currBldrCtx->blockCount());
        }


        B.takeNodes(UpdatedN);
        ExplodedNodeSet Dst2;
        evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, LC), InitVal, true);
        B.addNodes(Dst2);
      }
    }
    else {
      B.generateNode(DS, N, state);
    }
  }
}
开发者ID:8l,项目名称:emscripten-fastcomp-clang,代码行数:69,代码来源:ExprEngineC.cpp

示例3: Bldr

void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, 
                                    ExplodedNode *Pred,
                                    ExplodedNodeSet &Dst) {
  StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
  switch (U->getOpcode()) {
    default: {
      Bldr.takeNodes(Pred);
      ExplodedNodeSet Tmp;
      VisitIncrementDecrementOperator(U, Pred, Tmp);
      Bldr.addNodes(Tmp);
    }
      break;
    case UO_Real: {
      const Expr *Ex = U->getSubExpr()->IgnoreParens();
      ExplodedNodeSet Tmp;
      Visit(Ex, Pred, Tmp);
      
      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
        
        // FIXME: We don't have complex SValues yet.
        if (Ex->getType()->isAnyComplexType()) {
          // Just report "Unknown."
          continue;
        }
        
        // For all other types, UO_Real is an identity operation.
        assert (U->getType() == Ex->getType());
        const ProgramState *state = (*I)->getState();
        const LocationContext *LCtx = (*I)->getLocationContext();
        Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
                                                 state->getSVal(Ex, LCtx)));
      }
      
      break;
    }
      
    case UO_Imag: {
      
      const Expr *Ex = U->getSubExpr()->IgnoreParens();
      ExplodedNodeSet Tmp;
      Visit(Ex, Pred, Tmp);
      
      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
        // FIXME: We don't have complex SValues yet.
        if (Ex->getType()->isAnyComplexType()) {
          // Just report "Unknown."
          continue;
        }
        
        // For all other types, UO_Imag returns 0.
        const ProgramState *state = (*I)->getState();
        const LocationContext *LCtx = (*I)->getLocationContext();
        SVal X = svalBuilder.makeZeroVal(Ex->getType());
        Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X));
      }
      
      break;
    }
      
    case UO_Plus:
      assert(!U->isLValue());
      // FALL-THROUGH.
    case UO_Deref:
    case UO_AddrOf:
    case UO_Extension: {
      
      // Unary "+" is a no-op, similar to a parentheses.  We still have places
      // where it may be a block-level expression, so we need to
      // generate an extra node that just propagates the value of the
      // subexpression.
      
      const Expr *Ex = U->getSubExpr()->IgnoreParens();
      ExplodedNodeSet Tmp;
      Visit(Ex, Pred, Tmp);
      
      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
        const ProgramState *state = (*I)->getState();
        const LocationContext *LCtx = (*I)->getLocationContext();
        Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
                                                 state->getSVal(Ex, LCtx)));
      }
      
      break;
    }
      
    case UO_LNot:
    case UO_Minus:
    case UO_Not: {
      assert (!U->isLValue());
      const Expr *Ex = U->getSubExpr()->IgnoreParens();
      ExplodedNodeSet Tmp;
      Visit(Ex, Pred, Tmp);
      
      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
        const ProgramState *state = (*I)->getState();
        const LocationContext *LCtx = (*I)->getLocationContext();
        
        // Get the value of the subexpression.
        SVal V = state->getSVal(Ex, LCtx);
        
//.........这里部分代码省略.........
开发者ID:Andersbakken,项目名称:clang,代码行数:101,代码来源:ExprEngineC.cpp

示例4: CrashInfo

/// The call exit is simulated with a sequence of nodes, which occur between
/// CallExitBegin and CallExitEnd. The following operations occur between the
/// two program points:
/// 1. CallExitBegin (triggers the start of call exit sequence)
/// 2. Bind the return value
/// 3. Run Remove dead bindings to clean up the dead symbols from the callee.
/// 4. CallExitEnd (switch to the caller context)
/// 5. PostStmt<CallExpr>
void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
  // Step 1 CEBNode was generated before the call.
  PrettyStackTraceLocationContext CrashInfo(CEBNode->getLocationContext());
  const StackFrameContext *calleeCtx =
      CEBNode->getLocationContext()->getCurrentStackFrame();

  // The parent context might not be a stack frame, so make sure we
  // look up the first enclosing stack frame.
  const StackFrameContext *callerCtx =
    calleeCtx->getParent()->getCurrentStackFrame();

  const Stmt *CE = calleeCtx->getCallSite();
  ProgramStateRef state = CEBNode->getState();
  // Find the last statement in the function and the corresponding basic block.
  const Stmt *LastSt = nullptr;
  const CFGBlock *Blk = nullptr;
  std::tie(LastSt, Blk) = getLastStmt(CEBNode);

  // Generate a CallEvent /before/ cleaning the state, so that we can get the
  // correct value for 'this' (if necessary).
  CallEventManager &CEMgr = getStateManager().getCallEventManager();
  CallEventRef<> Call = CEMgr.getCaller(calleeCtx, state);

  // Step 2: generate node with bound return value: CEBNode -> BindedRetNode.

  // If the callee returns an expression, bind its value to CallExpr.
  if (CE) {
    if (const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
      const LocationContext *LCtx = CEBNode->getLocationContext();
      SVal V = state->getSVal(RS, LCtx);

      // Ensure that the return type matches the type of the returned Expr.
      if (wasDifferentDeclUsedForInlining(Call, calleeCtx)) {
        QualType ReturnedTy =
          CallEvent::getDeclaredResultType(calleeCtx->getDecl());
        if (!ReturnedTy.isNull()) {
          if (const Expr *Ex = dyn_cast<Expr>(CE)) {
            V = adjustReturnValue(V, Ex->getType(), ReturnedTy,
                                  getStoreManager());
          }
        }
      }

      state = state->BindExpr(CE, callerCtx, V);
    }

    // Bind the constructed object value to CXXConstructExpr.
    if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
      loc::MemRegionVal This =
        svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx);
      SVal ThisV = state->getSVal(This);

      // If the constructed object is a temporary prvalue, get its bindings.
      if (isTemporaryPRValue(CCE, ThisV))
        ThisV = state->getSVal(ThisV.castAs<Loc>());

      state = state->BindExpr(CCE, callerCtx, ThisV);
    }
  }

  // Step 3: BindedRetNode -> CleanedNodes
  // If we can find a statement and a block in the inlined function, run remove
  // dead bindings before returning from the call. This is important to ensure
  // that we report the issues such as leaks in the stack contexts in which
  // they occurred.
  ExplodedNodeSet CleanedNodes;
  if (LastSt && Blk && AMgr.options.AnalysisPurgeOpt != PurgeNone) {
    static SimpleProgramPointTag retValBind("ExprEngine", "Bind Return Value");
    PostStmt Loc(LastSt, calleeCtx, &retValBind);
    bool isNew;
    ExplodedNode *BindedRetNode = G.getNode(Loc, state, false, &isNew);
    BindedRetNode->addPredecessor(CEBNode, G);
    if (!isNew)
      return;

    NodeBuilderContext Ctx(getCoreEngine(), Blk, BindedRetNode);
    currBldrCtx = &Ctx;
    // Here, we call the Symbol Reaper with 0 statement and callee location
    // context, telling it to clean up everything in the callee's context
    // (and its children). We use the callee's function body as a diagnostic
    // statement, with which the program point will be associated.
    removeDead(BindedRetNode, CleanedNodes, nullptr, calleeCtx,
               calleeCtx->getAnalysisDeclContext()->getBody(),
               ProgramPoint::PostStmtPurgeDeadSymbolsKind);
    currBldrCtx = nullptr;
  } else {
    CleanedNodes.Add(CEBNode);
  }

  for (ExplodedNodeSet::iterator I = CleanedNodes.begin(),
                                 E = CleanedNodes.end(); I != E; ++I) {

//.........这里部分代码省略.........
开发者ID:JuliaLang,项目名称:clang,代码行数:101,代码来源:ExprEngineCallAndReturn.cpp

示例5: OSAtomicLoadTag

bool OSAtomicChecker::evalOSAtomicCompareAndSwap(CheckerContext &C, 
                                                 const CallExpr *CE) {
  // Not enough arguments to match OSAtomicCompareAndSwap?
  if (CE->getNumArgs() != 3)
    return false;

  ASTContext &Ctx = C.getASTContext();
  const Expr *oldValueExpr = CE->getArg(0);
  QualType oldValueType = Ctx.getCanonicalType(oldValueExpr->getType());

  const Expr *newValueExpr = CE->getArg(1);
  QualType newValueType = Ctx.getCanonicalType(newValueExpr->getType());

  // Do the types of 'oldValue' and 'newValue' match?
  if (oldValueType != newValueType)
    return false;

  const Expr *theValueExpr = CE->getArg(2);
  const PointerType *theValueType=theValueExpr->getType()->getAs<PointerType>();

  // theValueType not a pointer?
  if (!theValueType)
    return false;

  QualType theValueTypePointee =
    Ctx.getCanonicalType(theValueType->getPointeeType()).getUnqualifiedType();

  // The pointee must match newValueType and oldValueType.
  if (theValueTypePointee != newValueType)
    return false;

  static SimpleProgramPointTag OSAtomicLoadTag("OSAtomicChecker : Load");
  static SimpleProgramPointTag OSAtomicStoreTag("OSAtomicChecker : Store");
  
  // Load 'theValue'.
  ExprEngine &Engine = C.getEngine();
  const ProgramState *state = C.getState();
  ExplodedNodeSet Tmp;
  SVal location = state->getSVal(theValueExpr);
  // Here we should use the value type of the region as the load type, because
  // we are simulating the semantics of the function, not the semantics of 
  // passing argument. So the type of theValue expr is not we are loading.
  // But usually the type of the varregion is not the type we want either,
  // we still need to do a CastRetrievedVal in store manager. So actually this
  // LoadTy specifying can be omitted. But we put it here to emphasize the 
  // semantics.
  QualType LoadTy;
  if (const TypedValueRegion *TR =
      dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) {
    LoadTy = TR->getValueType();
  }
  Engine.evalLoad(Tmp, theValueExpr, C.getPredecessor(), 
                  state, location, &OSAtomicLoadTag, LoadTy);

  if (Tmp.empty()) {
    // If no nodes were generated, other checkers must generated sinks. But 
    // since the builder state was restored, we set it manually to prevent 
    // auto transition.
    // FIXME: there should be a better approach.
    C.getNodeBuilder().BuildSinks = true;
    return true;
  }
 
  for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end();
       I != E; ++I) {

    ExplodedNode *N = *I;
    const ProgramState *stateLoad = N->getState();

    // Use direct bindings from the environment since we are forcing a load
    // from a location that the Environment would typically not be used
    // to bind a value.
    SVal theValueVal_untested = stateLoad->getSVal(theValueExpr, true);

    SVal oldValueVal_untested = stateLoad->getSVal(oldValueExpr);

    // FIXME: Issue an error.
    if (theValueVal_untested.isUndef() || oldValueVal_untested.isUndef()) {
      return false;
    }
    
    DefinedOrUnknownSVal theValueVal =
      cast<DefinedOrUnknownSVal>(theValueVal_untested);
    DefinedOrUnknownSVal oldValueVal =
      cast<DefinedOrUnknownSVal>(oldValueVal_untested);

    SValBuilder &svalBuilder = Engine.getSValBuilder();

    // Perform the comparison.
    DefinedOrUnknownSVal Cmp =
      svalBuilder.evalEQ(stateLoad,theValueVal,oldValueVal);

    const ProgramState *stateEqual = stateLoad->assume(Cmp, true);

    // Were they equal?
    if (stateEqual) {
      // Perform the store.
      ExplodedNodeSet TmpStore;
      SVal val = stateEqual->getSVal(newValueExpr);

//.........这里部分代码省略.........
开发者ID:lygstate,项目名称:safecode-mirror,代码行数:101,代码来源:OSAtomicChecker.cpp

示例6: assert

void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, 
                                       const MemRegion *Dest,
                                       ExplodedNode *Pred,
                                       ExplodedNodeSet &destNodes) {

  const CXXConstructorDecl *CD = E->getConstructor();
  assert(CD);
  
#if 0
  if (!(CD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall()))
    // FIXME: invalidate the object.
    return;
#endif
  
  // Evaluate other arguments.
  ExplodedNodeSet argsEvaluated;
  const FunctionProtoType *FnType = CD->getType()->getAs<FunctionProtoType>();
  evalArguments(E->arg_begin(), E->arg_end(), FnType, Pred, argsEvaluated);

#if 0
  // Is the constructor elidable?
  if (E->isElidable()) {
    VisitAggExpr(E->getArg(0), destNodes, Pred, Dst);
    // FIXME: this is here to force propagation if VisitAggExpr doesn't
    if (destNodes.empty())
      destNodes.Add(Pred);
    return;
  }
#endif
  
  // Perform the previsit of the constructor.
  ExplodedNodeSet destPreVisit;
  getCheckerManager().runCheckersForPreStmt(destPreVisit, argsEvaluated, E, 
                                            *this);
  
  // Evaluate the constructor.  Currently we don't now allow checker-specific
  // implementations of specific constructors (as we do with ordinary
  // function calls.  We can re-evaluate this in the future.
  
#if 0
  // Inlining currently isn't fully implemented.

  if (AMgr.shouldInlineCall()) {
    if (!Dest)
      Dest =
        svalBuilder.getRegionManager().getCXXTempObjectRegion(E,
                                                  Pred->getLocationContext());

    // The callee stack frame context used to create the 'this'
    // parameter region.
    const StackFrameContext *SFC = 
      AMgr.getStackFrame(CD, Pred->getLocationContext(),
                         E, currentBuilderContext->getBlock(),
                         currentStmtIdx);

    // Create the 'this' region.
    const CXXThisRegion *ThisR =
      getCXXThisRegion(E->getConstructor()->getParent(), SFC);

    CallEnter Loc(E, SFC, Pred->getLocationContext());

    StmtNodeBuilder Bldr(argsEvaluated, destNodes, *currentBuilderContext);
    for (ExplodedNodeSet::iterator NI = argsEvaluated.begin(),
                                  NE = argsEvaluated.end(); NI != NE; ++NI) {
      const ProgramState *state = (*NI)->getState();
      // Setup 'this' region, so that the ctor is evaluated on the object pointed
      // by 'Dest'.
      state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
      Bldr.generateNode(Loc, *NI, state);
    }
  }
#endif
  
  // Default semantics: invalidate all regions passed as arguments.
  ExplodedNodeSet destCall;
  {
    StmtNodeBuilder Bldr(destPreVisit, destCall, *currentBuilderContext);
    for (ExplodedNodeSet::iterator
        i = destPreVisit.begin(), e = destPreVisit.end();
        i != e; ++i)
    {
      ExplodedNode *Pred = *i;
      const LocationContext *LC = Pred->getLocationContext();
      const ProgramState *state = Pred->getState();

      state = invalidateArguments(state, CallOrObjCMessage(E, state, LC), LC);
      Bldr.generateNode(E, Pred, state);
    }
  }
  // Do the post visit.
  getCheckerManager().runCheckersForPostStmt(destNodes, destCall, E, *this);  
}
开发者ID:Andersbakken,项目名称:clang,代码行数:92,代码来源:ExprEngineCXX.cpp

示例7: assert

void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
                                            ExplodedNode *Pred,
                                            ExplodedNodeSet &Dst) {
  
  // ObjCForCollectionStmts are processed in two places.  This method
  // handles the case where an ObjCForCollectionStmt* occurs as one of the
  // statements within a basic block.  This transfer function does two things:
  //
  //  (1) binds the next container value to 'element'.  This creates a new
  //      node in the ExplodedGraph.
  //
  //  (2) binds the value 0/1 to the ObjCForCollectionStmt* itself, indicating
  //      whether or not the container has any more elements.  This value
  //      will be tested in ProcessBranch.  We need to explicitly bind
  //      this value because a container can contain nil elements.
  //
  // FIXME: Eventually this logic should actually do dispatches to
  //   'countByEnumeratingWithState:objects:count:' (NSFastEnumeration).
  //   This will require simulating a temporary NSFastEnumerationState, either
  //   through an SVal or through the use of MemRegions.  This value can
  //   be affixed to the ObjCForCollectionStmt* instead of 0/1; when the loop
  //   terminates we reclaim the temporary (it goes out of scope) and we
  //   we can test if the SVal is 0 or if the MemRegion is null (depending
  //   on what approach we take).
  //
  //  For now: simulate (1) by assigning either a symbol or nil if the
  //    container is empty.  Thus this transfer function will by default
  //    result in state splitting.

  const Stmt *elem = S->getElement();
  ProgramStateRef state = Pred->getState();
  SVal elementV;
  
  if (const DeclStmt *DS = dyn_cast<DeclStmt>(elem)) {
    const VarDecl *elemD = cast<VarDecl>(DS->getSingleDecl());
    assert(elemD->getInit() == 0);
    elementV = state->getLValue(elemD, Pred->getLocationContext());
  }
  else {
    elementV = state->getSVal(elem, Pred->getLocationContext());
  }
  
  ExplodedNodeSet dstLocation;
  evalLocation(dstLocation, S, elem, Pred, state, elementV, NULL, false);

  ExplodedNodeSet Tmp;
  StmtNodeBuilder Bldr(Pred, Tmp, *currentBuilderContext);

  for (ExplodedNodeSet::iterator NI = dstLocation.begin(),
       NE = dstLocation.end(); NI!=NE; ++NI) {
    Pred = *NI;
    ProgramStateRef state = Pred->getState();
    const LocationContext *LCtx = Pred->getLocationContext();
    
    // Handle the case where the container still has elements.
    SVal TrueV = svalBuilder.makeTruthVal(1);
    ProgramStateRef hasElems = state->BindExpr(S, LCtx, TrueV);
    
    // Handle the case where the container has no elements.
    SVal FalseV = svalBuilder.makeTruthVal(0);
    ProgramStateRef noElems = state->BindExpr(S, LCtx, FalseV);
    
    if (loc::MemRegionVal *MV = dyn_cast<loc::MemRegionVal>(&elementV))
      if (const TypedValueRegion *R = 
          dyn_cast<TypedValueRegion>(MV->getRegion())) {
        // FIXME: The proper thing to do is to really iterate over the
        //  container.  We will do this with dispatch logic to the store.
        //  For now, just 'conjure' up a symbolic value.
        QualType T = R->getValueType();
        assert(Loc::isLocType(T));
        unsigned Count = currentBuilderContext->getCurrentBlockCount();
        SymbolRef Sym = SymMgr.getConjuredSymbol(elem, LCtx, T, Count);
        SVal V = svalBuilder.makeLoc(Sym);
        hasElems = hasElems->bindLoc(elementV, V);
        
        // Bind the location to 'nil' on the false branch.
        SVal nilV = svalBuilder.makeIntVal(0, T);
        noElems = noElems->bindLoc(elementV, nilV);
      }
    
    // Create the new nodes.
    Bldr.generateNode(S, Pred, hasElems);
    Bldr.generateNode(S, Pred, noElems);
  }

  // Finally, run any custom checkers.
  // FIXME: Eventually all pre- and post-checks should live in VisitStmt.
  getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
}
开发者ID:vkhromov,项目名称:freebsd,代码行数:89,代码来源:ExprEngineObjC.cpp

示例8: getStateManager

void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
                                  ExplodedNode *Pred,
                                  ExplodedNodeSet &Dst) {
  CallEventManager &CEMgr = getStateManager().getCallEventManager();
  CallEventRef<ObjCMethodCall> Msg =
    CEMgr.getObjCMethodCall(ME, Pred->getState(), Pred->getLocationContext());

  // Handle the previsits checks.
  ExplodedNodeSet dstPrevisit;
  getCheckerManager().runCheckersForPreObjCMessage(dstPrevisit, Pred,
                                                   *Msg, *this);
  ExplodedNodeSet dstGenericPrevisit;
  getCheckerManager().runCheckersForPreCall(dstGenericPrevisit, dstPrevisit,
                                            *Msg, *this);

  // Proceed with evaluate the message expression.
  ExplodedNodeSet dstEval;
  StmtNodeBuilder Bldr(dstGenericPrevisit, dstEval, *currentBuilderContext);

  for (ExplodedNodeSet::iterator DI = dstGenericPrevisit.begin(),
       DE = dstGenericPrevisit.end(); DI != DE; ++DI) {
    ExplodedNode *Pred = *DI;
    ProgramStateRef State = Pred->getState();
    CallEventRef<ObjCMethodCall> UpdatedMsg = Msg.cloneWithState(State);
    
    if (UpdatedMsg->isInstanceMessage()) {
      SVal recVal = UpdatedMsg->getReceiverSVal();
      if (!recVal.isUndef()) {
        // Bifurcate the state into nil and non-nil ones.
        DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
        
        ProgramStateRef notNilState, nilState;
        llvm::tie(notNilState, nilState) = State->assume(receiverVal);
        
        // There are three cases: can be nil or non-nil, must be nil, must be
        // non-nil. We ignore must be nil, and merge the rest two into non-nil.
        // FIXME: This ignores many potential bugs (<rdar://problem/11733396>).
        // Revisit once we have lazier constraints.
        if (nilState && !notNilState) {
          continue;
        }
        
        // Check if the "raise" message was sent.
        assert(notNilState);
        if (Msg->getSelector() == RaiseSel) {
          // If we raise an exception, for now treat it as a sink.
          // Eventually we will want to handle exceptions properly.
          Bldr.generateNode(currentStmt, Pred, State, true);
          continue;
        }
        
        // Generate a transition to non-Nil state.
        if (notNilState != State)
          Pred = Bldr.generateNode(currentStmt, Pred, notNilState);
      }
    } else {
      // Check for special class methods.
      if (const ObjCInterfaceDecl *Iface = Msg->getReceiverInterface()) {
        if (!NSExceptionII) {
          ASTContext &Ctx = getContext();
          NSExceptionII = &Ctx.Idents.get("NSException");
        }
        
        if (isSubclass(Iface, NSExceptionII)) {
          enum { NUM_RAISE_SELECTORS = 2 };
          
          // Lazily create a cache of the selectors.
          if (!NSExceptionInstanceRaiseSelectors) {
            ASTContext &Ctx = getContext();
            NSExceptionInstanceRaiseSelectors =
              new Selector[NUM_RAISE_SELECTORS];
            SmallVector<IdentifierInfo*, NUM_RAISE_SELECTORS> II;
            unsigned idx = 0;
            
            // raise:format:
            II.push_back(&Ctx.Idents.get("raise"));
            II.push_back(&Ctx.Idents.get("format"));
            NSExceptionInstanceRaiseSelectors[idx++] =
              Ctx.Selectors.getSelector(II.size(), &II[0]);
            
            // raise:format:arguments:
            II.push_back(&Ctx.Idents.get("arguments"));
            NSExceptionInstanceRaiseSelectors[idx++] =
              Ctx.Selectors.getSelector(II.size(), &II[0]);
          }
          
          Selector S = Msg->getSelector();
          bool RaisesException = false;
          for (unsigned i = 0; i < NUM_RAISE_SELECTORS; ++i) {
            if (S == NSExceptionInstanceRaiseSelectors[i]) {
              RaisesException = true;
              break;
            }
          }
          if (RaisesException) {
            // If we raise an exception, for now treat it as a sink.
            // Eventually we will want to handle exceptions properly.
            Bldr.generateNode(currentStmt, Pred, Pred->getState(), true);
            continue;
          }
//.........这里部分代码省略.........
开发者ID:vkhromov,项目名称:freebsd,代码行数:101,代码来源:ExprEngineObjC.cpp

示例9: UnknownVal

void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
                                       ExplodedNode *Pred,
                                       ExplodedNodeSet &destNodes) {
  const LocationContext *LCtx = Pred->getLocationContext();
  ProgramStateRef State = Pred->getState();

  SVal Target = UnknownVal();

  if (Optional<SVal> ElidedTarget =
          getObjectUnderConstruction(State, CE, LCtx)) {
    // We've previously modeled an elidable constructor by pretending that it in
    // fact constructs into the correct target. This constructor can therefore
    // be skipped.
    Target = *ElidedTarget;
    StmtNodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
    State = finishObjectConstruction(State, CE, LCtx);
    if (auto L = Target.getAs<Loc>())
      State = State->BindExpr(CE, LCtx, State->getSVal(*L, CE->getType()));
    Bldr.generateNode(CE, Pred, State);
    return;
  }

  // FIXME: Handle arrays, which run the same constructor for every element.
  // For now, we just run the first constructor (which should still invalidate
  // the entire array).

  EvalCallOptions CallOpts;
  auto C = getCurrentCFGElement().getAs<CFGConstructor>();
  assert(C || getCurrentCFGElement().getAs<CFGStmt>());
  const ConstructionContext *CC = C ? C->getConstructionContext() : nullptr;

  switch (CE->getConstructionKind()) {
  case CXXConstructExpr::CK_Complete: {
    std::tie(State, Target) =
        prepareForObjectConstruction(CE, State, LCtx, CC, CallOpts);
    break;
  }
  case CXXConstructExpr::CK_VirtualBase:
    // Make sure we are not calling virtual base class initializers twice.
    // Only the most-derived object should initialize virtual base classes.
    if (const Stmt *Outer = LCtx->getStackFrame()->getCallSite()) {
      const CXXConstructExpr *OuterCtor = dyn_cast<CXXConstructExpr>(Outer);
      if (OuterCtor) {
        switch (OuterCtor->getConstructionKind()) {
        case CXXConstructExpr::CK_NonVirtualBase:
        case CXXConstructExpr::CK_VirtualBase:
          // Bail out!
          destNodes.Add(Pred);
          return;
        case CXXConstructExpr::CK_Complete:
        case CXXConstructExpr::CK_Delegating:
          break;
        }
      }
    }
    LLVM_FALLTHROUGH;
  case CXXConstructExpr::CK_NonVirtualBase:
    // In C++17, classes with non-virtual bases may be aggregates, so they would
    // be initialized as aggregates without a constructor call, so we may have
    // a base class constructed directly into an initializer list without
    // having the derived-class constructor call on the previous stack frame.
    // Initializer lists may be nested into more initializer lists that
    // correspond to surrounding aggregate initializations.
    // FIXME: For now this code essentially bails out. We need to find the
    // correct target region and set it.
    // FIXME: Instead of relying on the ParentMap, we should have the
    // trigger-statement (InitListExpr in this case) passed down from CFG or
    // otherwise always available during construction.
    if (dyn_cast_or_null<InitListExpr>(LCtx->getParentMap().getParent(CE))) {
      MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
      Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(CE, LCtx));
      CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
      break;
    }
    LLVM_FALLTHROUGH;
  case CXXConstructExpr::CK_Delegating: {
    const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
    Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
                                              LCtx->getStackFrame());
    SVal ThisVal = State->getSVal(ThisPtr);

    if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) {
      Target = ThisVal;
    } else {
      // Cast to the base type.
      bool IsVirtual =
        (CE->getConstructionKind() == CXXConstructExpr::CK_VirtualBase);
      SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, CE->getType(),
                                                         IsVirtual);
      Target = BaseVal;
    }
    break;
  }
  }

  if (State != Pred->getState()) {
    static SimpleProgramPointTag T("ExprEngine",
                                   "Prepare for object construction");
    ExplodedNodeSet DstPrepare;
    StmtNodeBuilder BldrPrepare(Pred, DstPrepare, *currBldrCtx);
//.........这里部分代码省略.........
开发者ID:LegalizeAdulthood,项目名称:clang,代码行数:101,代码来源:ExprEngineCXX.cpp

示例10: getStateManager

void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
                                  ExplodedNode *Pred,
                                  ExplodedNodeSet &Dst) {
  CallEventManager &CEMgr = getStateManager().getCallEventManager();
  CallEventRef<ObjCMethodCall> Msg =
    CEMgr.getObjCMethodCall(ME, Pred->getState(), Pred->getLocationContext());

  // Handle the previsits checks.
  ExplodedNodeSet dstPrevisit;
  getCheckerManager().runCheckersForPreObjCMessage(dstPrevisit, Pred,
                                                   *Msg, *this);
  ExplodedNodeSet dstGenericPrevisit;
  getCheckerManager().runCheckersForPreCall(dstGenericPrevisit, dstPrevisit,
                                            *Msg, *this);

  // Proceed with evaluate the message expression.
  ExplodedNodeSet dstEval;
  StmtNodeBuilder Bldr(dstGenericPrevisit, dstEval, *currBldrCtx);

  for (ExplodedNodeSet::iterator DI = dstGenericPrevisit.begin(),
       DE = dstGenericPrevisit.end(); DI != DE; ++DI) {
    ExplodedNode *Pred = *DI;
    ProgramStateRef State = Pred->getState();
    CallEventRef<ObjCMethodCall> UpdatedMsg = Msg.cloneWithState(State);
    
    if (UpdatedMsg->isInstanceMessage()) {
      SVal recVal = UpdatedMsg->getReceiverSVal();
      if (!recVal.isUndef()) {
        // Bifurcate the state into nil and non-nil ones.
        DefinedOrUnknownSVal receiverVal =
            recVal.castAs<DefinedOrUnknownSVal>();

        ProgramStateRef notNilState, nilState;
        std::tie(notNilState, nilState) = State->assume(receiverVal);
        
        // There are three cases: can be nil or non-nil, must be nil, must be
        // non-nil. We ignore must be nil, and merge the rest two into non-nil.
        // FIXME: This ignores many potential bugs (<rdar://problem/11733396>).
        // Revisit once we have lazier constraints.
        if (nilState && !notNilState) {
          continue;
        }
        
        // Check if the "raise" message was sent.
        assert(notNilState);
        if (ObjCNoRet.isImplicitNoReturn(ME)) {
          // If we raise an exception, for now treat it as a sink.
          // Eventually we will want to handle exceptions properly.
          Bldr.generateSink(ME, Pred, State);
          continue;
        }
        
        // Generate a transition to non-Nil state.
        if (notNilState != State) {
          Pred = Bldr.generateNode(ME, Pred, notNilState);
          assert(Pred && "Should have cached out already!");
        }
      }
    } else {
      // Check for special class methods that are known to not return
      // and that we should treat as a sink.
      if (ObjCNoRet.isImplicitNoReturn(ME)) {
        // If we raise an exception, for now treat it as a sink.
        // Eventually we will want to handle exceptions properly.
        Bldr.generateSink(ME, Pred, Pred->getState());
        continue;
      }
    }

    defaultEvalCall(Bldr, Pred, *UpdatedMsg);
  }
  
  ExplodedNodeSet dstPostvisit;
  getCheckerManager().runCheckersForPostCall(dstPostvisit, dstEval,
                                             *Msg, *this);

  // Finally, perform the post-condition check of the ObjCMessageExpr and store
  // the created nodes in 'Dst'.
  getCheckerManager().runCheckersForPostObjCMessage(Dst, dstPostvisit,
                                                    *Msg, *this);
}
开发者ID:Bigcheese,项目名称:clang,代码行数:81,代码来源:ExprEngineObjC.cpp

示例11: assert

void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
                                                 ExplodedNode *Pred,
                                                 ExplodedNodeSet &Dst) {
  // Handle ++ and -- (both pre- and post-increment).
  assert (U->isIncrementDecrementOp());
  const Expr *Ex = U->getSubExpr()->IgnoreParens();
  
  const LocationContext *LCtx = Pred->getLocationContext();
  ProgramStateRef state = Pred->getState();
  SVal loc = state->getSVal(Ex, LCtx);
  
  // Perform a load.
  ExplodedNodeSet Tmp;
  evalLoad(Tmp, U, Ex, Pred, state, loc);
  
  ExplodedNodeSet Dst2;
  StmtNodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
  for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end();I!=E;++I) {
    
    state = (*I)->getState();
    assert(LCtx == (*I)->getLocationContext());
    SVal V2_untested = state->getSVal(Ex, LCtx);
    
    // Propagate unknown and undefined values.
    if (V2_untested.isUnknownOrUndef()) {
      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V2_untested));
      continue;
    }
    DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
    
    // Handle all other values.
    BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
    
    // If the UnaryOperator has non-location type, use its type to create the
    // constant value. If the UnaryOperator has location type, create the
    // constant with int type and pointer width.
    SVal RHS;
    
    if (U->getType()->isAnyPointerType())
      RHS = svalBuilder.makeArrayIndex(1);
    else if (U->getType()->isIntegralOrEnumerationType())
      RHS = svalBuilder.makeIntVal(1, U->getType());
    else
      RHS = UnknownVal();
    
    SVal Result = evalBinOp(state, Op, V2, RHS, U->getType());
    
    // Conjure a new symbol if necessary to recover precision.
    if (Result.isUnknown()){
      DefinedOrUnknownSVal SymVal =
        svalBuilder.conjureSymbolVal(0, Ex, LCtx, currBldrCtx->blockCount());
      Result = SymVal;
      
      // If the value is a location, ++/-- should always preserve
      // non-nullness.  Check if the original value was non-null, and if so
      // propagate that constraint.
      if (Loc::isLocType(U->getType())) {
        DefinedOrUnknownSVal Constraint =
        svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
        
        if (!state->assume(Constraint, true)) {
          // It isn't feasible for the original value to be null.
          // Propagate this constraint.
          Constraint = svalBuilder.evalEQ(state, SymVal,
                                       svalBuilder.makeZeroVal(U->getType()));
          
          
          state = state->assume(Constraint, false);
          assert(state);
        }
      }
    }
    
    // Since the lvalue-to-rvalue conversion is explicit in the AST,
    // we bind an l-value if the operator is prefix and an lvalue (in C++).
    if (U->isGLValue())
      state = state->BindExpr(U, LCtx, loc);
    else
      state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);
    
    // Perform the store.
    Bldr.takeNodes(*I);
    ExplodedNodeSet Dst3;
    evalStore(Dst3, U, U, *I, state, loc, Result);
    Bldr.addNodes(Dst3);
  }
  Dst.insert(Dst2);
}
开发者ID:8l,项目名称:emscripten-fastcomp-clang,代码行数:88,代码来源:ExprEngineC.cpp

示例12: getLastStmt

/// The call exit is simulated with a sequence of nodes, which occur between 
/// CallExitBegin and CallExitEnd. The following operations occur between the 
/// two program points:
/// 1. CallExitBegin (triggers the start of call exit sequence)
/// 2. Bind the return value
/// 3. Run Remove dead bindings to clean up the dead symbols from the callee.
/// 4. CallExitEnd (switch to the caller context)
/// 5. PostStmt<CallExpr>
void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
  // Step 1 CEBNode was generated before the call.

  const StackFrameContext *calleeCtx =
      CEBNode->getLocationContext()->getCurrentStackFrame();
  const LocationContext *callerCtx = calleeCtx->getParent();
  const Stmt *CE = calleeCtx->getCallSite();
  ProgramStateRef state = CEBNode->getState();
  // Find the last statement in the function and the corresponding basic block.
  const Stmt *LastSt = 0;
  const CFGBlock *Blk = 0;
  llvm::tie(LastSt, Blk) = getLastStmt(CEBNode);

  // Step 2: generate node with binded return value: CEBNode -> BindedRetNode.

  // If the callee returns an expression, bind its value to CallExpr.
  if (const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
    const LocationContext *LCtx = CEBNode->getLocationContext();
    SVal V = state->getSVal(RS, LCtx);
    state = state->BindExpr(CE, callerCtx, V);
  }

  // Bind the constructed object value to CXXConstructExpr.
  if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
    const CXXThisRegion *ThisR =
        getCXXThisRegion(CCE->getConstructor()->getParent(), calleeCtx);

    SVal ThisV = state->getSVal(ThisR);
    // Always bind the region to the CXXConstructExpr.
    state = state->BindExpr(CCE, CEBNode->getLocationContext(), ThisV);
  }

  static SimpleProgramPointTag retValBindTag("ExprEngine : Bind Return Value");
  PostStmt Loc(LastSt, calleeCtx, &retValBindTag);
  bool isNew;
  ExplodedNode *BindedRetNode = G.getNode(Loc, state, false, &isNew);
  BindedRetNode->addPredecessor(CEBNode, G);
  if (!isNew)
    return;

  // Step 3: BindedRetNode -> CleanedNodes
  // If we can find a statement and a block in the inlined function, run remove
  // dead bindings before returning from the call. This is important to ensure
  // that we report the issues such as leaks in the stack contexts in which
  // they occurred.
  ExplodedNodeSet CleanedNodes;
  if (LastSt && Blk) {
    NodeBuilderContext Ctx(getCoreEngine(), Blk, BindedRetNode);
    currentBuilderContext = &Ctx;
    // Here, we call the Symbol Reaper with 0 statement and caller location
    // context, telling it to clean up everything in the callee's context
    // (and it's children). We use LastStmt as a diagnostic statement, which
    // which the PreStmtPurge Dead point will be associated.
    removeDead(BindedRetNode, CleanedNodes, 0, callerCtx, LastSt,
               ProgramPoint::PostStmtPurgeDeadSymbolsKind);
    currentBuilderContext = 0;
  }

  for (ExplodedNodeSet::iterator I = CleanedNodes.begin(),
                                 E = CleanedNodes.end(); I != E; ++I) {

    // Step 4: Generate the CallExit and leave the callee's context.
    // CleanedNodes -> CEENode
    CallExitEnd Loc(CE, callerCtx);
    bool isNew;
    ExplodedNode *CEENode = G.getNode(Loc, (*I)->getState(), false, &isNew);
    CEENode->addPredecessor(*I, G);
    if (!isNew)
      return;

    // Step 5: Perform the post-condition check of the CallExpr and enqueue the
    // result onto the work list.
    // CEENode -> Dst -> WorkList
    ExplodedNodeSet Dst;
    NodeBuilderContext Ctx(Engine, calleeCtx->getCallSiteBlock(), CEENode);
    SaveAndRestore<const NodeBuilderContext*> NBCSave(currentBuilderContext,
        &Ctx);
    SaveAndRestore<unsigned> CBISave(currentStmtIdx, calleeCtx->getIndex());

    getCheckerManager().runCheckersForPostStmt(Dst, CEENode, CE, *this, true);

    // Enqueue the next element in the block.
    for (ExplodedNodeSet::iterator PSI = Dst.begin(), PSE = Dst.end();
                                   PSI != PSE; ++PSI) {
      Engine.getWorkList()->enqueue(*PSI, calleeCtx->getCallSiteBlock(),
                                    calleeCtx->getIndex()+1);
    }
  }
}
开发者ID:sandssss,项目名称:clang,代码行数:97,代码来源:ExprEngineCallAndReturn.cpp

示例13: assert

/// \brief Run checkers for evaluating a call.
/// Only one checker will evaluate the call.
void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst,
                                            const ExplodedNodeSet &Src,
                                            const CallExpr *CE,
                                            ExprEngine &Eng,
                                            GraphExpander *defaultEval) {
  if (EvalCallCheckers.empty()   &&
      InlineCallCheckers.empty() &&
      defaultEval == 0) {
    Dst.insert(Src);
    return;
  }

  for (ExplodedNodeSet::iterator
         NI = Src.begin(), NE = Src.end(); NI != NE; ++NI) {

    ExplodedNode *Pred = *NI;
    bool anyEvaluated = false;

    // First, check if any of the InlineCall callbacks can evaluate the call.
    assert(InlineCallCheckers.size() <= 1 &&
           "InlineCall is a special hacky callback to allow intrusive"
           "evaluation of the call (which simulates inlining). It is "
           "currently only used by OSAtomicChecker and should go away "
           "at some point.");
    for (std::vector<InlineCallFunc>::iterator
           EI = InlineCallCheckers.begin(), EE = InlineCallCheckers.end();
         EI != EE; ++EI) {
      ExplodedNodeSet checkDst;
      bool evaluated = (*EI)(CE, Eng, Pred, checkDst);
      assert(!(evaluated && anyEvaluated)
             && "There are more than one checkers evaluating the call");
      if (evaluated) {
        anyEvaluated = true;
        Dst.insert(checkDst);
#ifdef NDEBUG
        break; // on release don't check that no other checker also evals.
#endif
      }
    }

#ifdef NDEBUG // on release don't check that no other checker also evals.
    if (anyEvaluated) {
      break;
    }
#endif

    // Next, check if any of the EvalCall callbacks can evaluate the call.
    for (std::vector<EvalCallFunc>::iterator
           EI = EvalCallCheckers.begin(), EE = EvalCallCheckers.end();
         EI != EE; ++EI) {
      ExplodedNodeSet checkDst;
      ProgramPoint::Kind K = ProgramPoint::PostStmtKind;
      const ProgramPoint &L = ProgramPoint::getProgramPoint(CE, K,
                                Pred->getLocationContext(), EI->Checker);
      bool evaluated = false;
      { // CheckerContext generates transitions(populates checkDest) on
        // destruction, so introduce the scope to make sure it gets properly
        // populated.
        CheckerContext C(checkDst, Eng.getBuilder(), Eng, Pred, L, 0);
        evaluated = (*EI)(CE, C);
      }
      assert(!(evaluated && anyEvaluated)
             && "There are more than one checkers evaluating the call");
      if (evaluated) {
        anyEvaluated = true;
        Dst.insert(checkDst);
#ifdef NDEBUG
        break; // on release don't check that no other checker also evals.
#endif
      }
    }
    
    // If none of the checkers evaluated the call, ask ExprEngine to handle it.
    if (!anyEvaluated) {
      if (defaultEval)
        defaultEval->expandGraph(Dst, Pred);
      else
        Dst.insert(Pred);
    }
  }
}
开发者ID:asdlei00,项目名称:freebsd,代码行数:83,代码来源:CheckerManager.cpp

示例14: enqueue

void CoreEngine::enqueue(ExplodedNodeSet &Set) {
  for (ExplodedNodeSet::iterator I = Set.begin(),
                                 E = Set.end(); I != E; ++I) {
    WList->enqueue(*I);
  }
}
开发者ID:FrOSt-Foundation,项目名称:clang,代码行数:6,代码来源:CoreEngine.cpp

示例15: getCheckerManager

void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
                                    ExplodedNode *Pred,
                                    ExplodedNodeSet &Dst) {
  // FIXME: Prechecks eventually go in ::Visit().
  ExplodedNodeSet CheckedSet;
  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);

  ExplodedNodeSet EvalSet;
  StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);

  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
       I != E; ++I) {
    switch (U->getOpcode()) {
    default: {
      Bldr.takeNodes(*I);
      ExplodedNodeSet Tmp;
      VisitIncrementDecrementOperator(U, *I, Tmp);
      Bldr.addNodes(Tmp);
      break;
    }
    case UO_Real: {
      const Expr *Ex = U->getSubExpr()->IgnoreParens();

      // FIXME: We don't have complex SValues yet.
      if (Ex->getType()->isAnyComplexType()) {
        // Just report "Unknown."
        break;
      }

      // For all other types, UO_Real is an identity operation.
      assert (U->getType() == Ex->getType());
      ProgramStateRef state = (*I)->getState();
      const LocationContext *LCtx = (*I)->getLocationContext();
      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
                                               state->getSVal(Ex, LCtx)));
      break;
    }

    case UO_Imag: {
      const Expr *Ex = U->getSubExpr()->IgnoreParens();
      // FIXME: We don't have complex SValues yet.
      if (Ex->getType()->isAnyComplexType()) {
        // Just report "Unknown."
        break;
      }
      // For all other types, UO_Imag returns 0.
      ProgramStateRef state = (*I)->getState();
      const LocationContext *LCtx = (*I)->getLocationContext();
      SVal X = svalBuilder.makeZeroVal(Ex->getType());
      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X));
      break;
    }

    case UO_Plus:
      assert(!U->isGLValue());
      // FALL-THROUGH.
    case UO_Deref:
    case UO_AddrOf:
    case UO_Extension: {
      // FIXME: We can probably just have some magic in Environment::getSVal()
      // that propagates values, instead of creating a new node here.
      //
      // Unary "+" is a no-op, similar to a parentheses.  We still have places
      // where it may be a block-level expression, so we need to
      // generate an extra node that just propagates the value of the
      // subexpression.
      const Expr *Ex = U->getSubExpr()->IgnoreParens();
      ProgramStateRef state = (*I)->getState();
      const LocationContext *LCtx = (*I)->getLocationContext();
      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
                                               state->getSVal(Ex, LCtx)));
      break;
    }

    case UO_LNot:
    case UO_Minus:
    case UO_Not: {
      assert (!U->isGLValue());
      const Expr *Ex = U->getSubExpr()->IgnoreParens();
      ProgramStateRef state = (*I)->getState();
      const LocationContext *LCtx = (*I)->getLocationContext();

      // Get the value of the subexpression.
      SVal V = state->getSVal(Ex, LCtx);

      if (V.isUnknownOrUndef()) {
        Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V));
        break;
      }

      switch (U->getOpcode()) {
        default:
          llvm_unreachable("Invalid Opcode.");
        case UO_Not:
          // FIXME: Do we need to handle promotions?
          state = state->BindExpr(U, LCtx, evalComplement(V.castAs<NonLoc>()));
          break;
        case UO_Minus:
          // FIXME: Do we need to handle promotions?
          state = state->BindExpr(U, LCtx, evalMinus(V.castAs<NonLoc>()));
//.........这里部分代码省略.........
开发者ID:hsorby,项目名称:opencor,代码行数:101,代码来源:ExprEngineC.cpp


注:本文中的ExplodedNodeSet类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。