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


C++ ExplodedNodeSet::Add方法代码示例

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


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

示例1: VisitCXXConstructExpr

void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, 
                                         const MemRegion *Dest,
                                         ExplodedNode *Pred,
                                         ExplodedNodeSet &Dst) {
  if (!Dest)
    Dest = svalBuilder.getRegionManager().getCXXTempObjectRegion(E,
                                                    Pred->getLocationContext());

  if (E->isElidable()) {
    VisitAggExpr(E->getArg(0), Dest, Pred, Dst);
    // FIXME: this is here to force propogation if VisitAggExpr doesn't
    if (Dst.empty())
      Dst.Add(Pred);
    return;
  }

  const CXXConstructorDecl *CD = E->getConstructor();
  assert(CD);

  if (!(CD->isThisDeclarationADefinition() && AMgr.shouldInlineCall()))
    // FIXME: invalidate the object.
    return;

  
  // Evaluate other arguments.
  ExplodedNodeSet argsEvaluated;
  const FunctionProtoType *FnType = CD->getType()->getAs<FunctionProtoType>();
  evalArguments(E->arg_begin(), E->arg_end(), FnType, Pred, argsEvaluated);
  // The callee stack frame context used to create the 'this' parameter region.
  const StackFrameContext *SFC = AMgr.getStackFrame(CD, 
                                                    Pred->getLocationContext(),
                                                    E, Builder->getBlock(),
                                                    Builder->getIndex());

  const CXXThisRegion *ThisR =getCXXThisRegion(E->getConstructor()->getParent(),
                                               SFC);

  CallEnter Loc(E, SFC, Pred->getLocationContext());
  for (ExplodedNodeSet::iterator NI = argsEvaluated.begin(),
                                 NE = argsEvaluated.end(); NI != NE; ++NI) {
    const GRState *state = GetState(*NI);
    // Setup 'this' region, so that the ctor is evaluated on the object pointed
    // by 'Dest'.
    state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
    ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
    if (N)
      Dst.Add(N);
  }
}
开发者ID:syoyo,项目名称:clang,代码行数:49,代码来源:CXXExprEngine.cpp

示例2: ExecuteWorkListWithInitialState

void CoreEngine::ExecuteWorkListWithInitialState(const LocationContext *L, 
                                                 unsigned Steps,
                                                 const ProgramState *InitState, 
                                                 ExplodedNodeSet &Dst) {
  ExecuteWorkList(L, Steps, InitState);
  for (SmallVectorImpl<ExplodedNode*>::iterator I = G->EndNodes.begin(), 
                                           E = G->EndNodes.end(); I != E; ++I) {
    Dst.Add(*I);
  }
}
开发者ID:lygstate,项目名称:safecode-mirror,代码行数:10,代码来源:CoreEngine.cpp

示例3: ExecuteWorkListWithInitialState

bool CoreEngine::ExecuteWorkListWithInitialState(const LocationContext *L,
                                                 unsigned Steps,
                                                 ProgramStateRef InitState, 
                                                 ExplodedNodeSet &Dst) {
  bool DidNotFinish = ExecuteWorkList(L, Steps, InitState);
  for (ExplodedGraph::eop_iterator I = G->eop_begin(), 
                                   E = G->eop_end(); I != E; ++I) {
    Dst.Add(*I);
  }
  return DidNotFinish;
}
开发者ID:FrOSt-Foundation,项目名称:clang,代码行数:11,代码来源:CoreEngine.cpp

示例4: VisitCXXMemberCallExpr

void GRExprEngine::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, 
                                          ExplodedNode *Pred, 
                                          ExplodedNodeSet &Dst) {
  // Get the method type.
  const FunctionProtoType *FnType = 
                       MCE->getCallee()->getType()->getAs<FunctionProtoType>();
  assert(FnType && "Method type not available");

  // Evaluate explicit arguments with a worklist.
  ExplodedNodeSet ArgsEvaluated;
  EvalArguments(MCE->arg_begin(), MCE->arg_end(), FnType, Pred, ArgsEvaluated);
 
  // Evaluate the implicit object argument.
  ExplodedNodeSet AllArgsEvaluated;
  const MemberExpr *ME = dyn_cast<MemberExpr>(MCE->getCallee()->IgnoreParens());
  if (!ME)
    return;
  Expr *ObjArgExpr = ME->getBase();
  for (ExplodedNodeSet::iterator I = ArgsEvaluated.begin(), 
                                 E = ArgsEvaluated.end(); I != E; ++I) {
    if (ME->isArrow())
      Visit(ObjArgExpr, *I, AllArgsEvaluated);
    else
      VisitLValue(ObjArgExpr, *I, AllArgsEvaluated);
  }

  const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
  assert(MD && "not a CXXMethodDecl?");

  if (!(MD->isThisDeclarationADefinition() && AMgr.shouldInlineCall()))
    // FIXME: conservative method call evaluation.
    return;

  const StackFrameContext *SFC = AMgr.getStackFrame(MD, 
                                                    Pred->getLocationContext(),
                                                    MCE, 
                                                    Builder->getBlock(), 
                                                    Builder->getIndex());
  const CXXThisRegion *ThisR = getCXXThisRegion(MD, SFC);
  CallEnter Loc(MCE, SFC->getAnalysisContext(), Pred->getLocationContext());
  for (ExplodedNodeSet::iterator I = AllArgsEvaluated.begin(),
         E = AllArgsEvaluated.end(); I != E; ++I) {
    // Set up 'this' region.
    const GRState *state = GetState(*I);
    state = state->bindLoc(loc::MemRegionVal(ThisR),state->getSVal(ObjArgExpr));
    ExplodedNode *N = Builder->generateNode(Loc, state, *I);
    if (N)
      Dst.Add(N);
  }
}
开发者ID:CPFL,项目名称:guc,代码行数:50,代码来源:GRCXXExprEngine.cpp

示例5: VisitCXXCatchStmt

void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS,
                                   ExplodedNode *Pred,
                                   ExplodedNodeSet &Dst) {
  const VarDecl *VD = CS->getExceptionDecl();
  if (!VD) {
    Dst.Add(Pred);
    return;
  }

  const LocationContext *LCtx = Pred->getLocationContext();
  SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(),
                                        currBldrCtx->blockCount());
  ProgramStateRef state = Pred->getState();
  state = state->bindLoc(state->getLValue(VD, LCtx), V);

  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
  Bldr.generateNode(CS, Pred, state);
}
开发者ID:DevO2012,项目名称:clang-with-ms-abi-support,代码行数:18,代码来源:ExprEngineCXX.cpp

示例6: VisitCXXConstructExpr

void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
        ExplodedNode *Pred,
        ExplodedNodeSet &Dst) {
    if (E->isElidable()) {
        VisitAggExpr(E->getArg(0), Dest, Pred, Dst);
        return;
    }

    const CXXConstructorDecl *CD = E->getConstructor();
    assert(CD);

    if (!(CD->isThisDeclarationADefinition() && AMgr.shouldInlineCall()))
        // FIXME: invalidate the object.
        return;


    // Evaluate other arguments.
    ExplodedNodeSet ArgsEvaluated;
    const FunctionProtoType *FnType = CD->getType()->getAs<FunctionProtoType>();
    EvalArguments(E->arg_begin(), E->arg_end(), FnType, Pred, ArgsEvaluated);
    // The callee stack frame context used to create the 'this' parameter region.
    const StackFrameContext *SFC = AMgr.getStackFrame(CD,
                                   Pred->getLocationContext(),
                                   E, Builder->getBlock(), Builder->getIndex());

    const CXXThisRegion *ThisR = getCXXThisRegion(E->getConstructor(), SFC);

    CallEnter Loc(E, SFC->getAnalysisContext(), Pred->getLocationContext());
    for (ExplodedNodeSet::iterator NI = ArgsEvaluated.begin(),
            NE = ArgsEvaluated.end(); NI != NE; ++NI) {
        const GRState *state = GetState(*NI);
        // Setup 'this' region.
        state = state->bindLoc(loc::MemRegionVal(ThisR), Dest);
        ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
        if (N)
            Dst.Add(N);
    }
}
开发者ID:lgerbarg,项目名称:clang,代码行数:38,代码来源:GRCXXExprEngine.cpp

示例7: removeDeadOnEndOfFunction

void ExprEngine::removeDeadOnEndOfFunction(NodeBuilderContext& BC,
                                           ExplodedNode *Pred,
                                           ExplodedNodeSet &Dst) {
  // 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(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:JuliaLang,项目名称:clang,代码行数:23,代码来源:ExprEngineCallAndReturn.cpp

示例8: processCallExit

/// 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

示例9: VisitCXXConstructExpr

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

  const MemRegion *Target = nullptr;

  // 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).

  switch (CE->getConstructionKind()) {
  case CXXConstructExpr::CK_Complete: {
    Target = getRegionForConstructedObject(CE, Pred, *this, currStmtIdx);
    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->getCurrentStackFrame()->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;
        }
      }
    }
    // FALLTHROUGH
  case CXXConstructExpr::CK_NonVirtualBase:
  case CXXConstructExpr::CK_Delegating: {
    const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
    Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
                                              LCtx->getCurrentStackFrame());
    SVal ThisVal = State->getSVal(ThisPtr);

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

  CallEventManager &CEMgr = getStateManager().getCallEventManager();
  CallEventRef<CXXConstructorCall> Call =
    CEMgr.getCXXConstructorCall(CE, Target, State, LCtx);

  ExplodedNodeSet DstPreVisit;
  getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this);

  ExplodedNodeSet PreInitialized;
  {
    StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
    if (CE->requiresZeroInitialization()) {
      // Type of the zero doesn't matter.
      SVal ZeroVal = svalBuilder.makeZeroVal(getContext().CharTy);

      for (ExplodedNodeSet::iterator I = DstPreVisit.begin(),
                                     E = DstPreVisit.end();
           I != E; ++I) {
        ProgramStateRef State = (*I)->getState();
        // FIXME: Once we properly handle constructors in new-expressions, we'll
        // need to invalidate the region before setting a default value, to make
        // sure there aren't any lingering bindings around. This probably needs
        // to happen regardless of whether or not the object is zero-initialized
        // to handle random fields of a placement-initialized object picking up
        // old bindings. We might only want to do it when we need to, though.
        // FIXME: This isn't actually correct for arrays -- we need to zero-
        // initialize the entire array, not just the first element -- but our
        // handling of arrays everywhere else is weak as well, so this shouldn't
        // actually make things worse. Placement new makes this tricky as well,
        // since it's then possible to be initializing one part of a multi-
        // dimensional array.
        State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal);
        Bldr.generateNode(CE, *I, State, /*tag=*/nullptr,
                          ProgramPoint::PreStmtKind);
      }
    }
  }

  ExplodedNodeSet DstPreCall;
  getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized,
                                            *Call, *this);

  ExplodedNodeSet DstEvaluated;
  StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
//.........这里部分代码省略.........
开发者ID:alessandrostone,项目名称:metashell,代码行数:101,代码来源:ExprEngineCXX.cpp

示例10: VisitCXXConstructExpr

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

示例11: VisitCXXConstructExpr

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

示例12: processCallExit

/// 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();

    // 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 = 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)) {
        loc::MemRegionVal This =
            svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx);
        SVal ThisV = state->getSVal(This);

        // 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;
    } else {
        CleanedNodes.Add(CEBNode);
    }

    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(),
//.........这里部分代码省略.........
开发者ID:FrOSt-Foundation,项目名称:clang,代码行数:101,代码来源:ExprEngineCallAndReturn.cpp


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