本文整理汇总了C++中ExplodedNodeSet::empty方法的典型用法代码示例。如果您正苦于以下问题:C++ ExplodedNodeSet::empty方法的具体用法?C++ ExplodedNodeSet::empty怎么用?C++ ExplodedNodeSet::empty使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ExplodedNodeSet
的用法示例。
在下文中一共展示了ExplodedNodeSet::empty方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: expandGraphWithCheckers
static void expandGraphWithCheckers(CHECK_CTX checkCtx,
ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src) {
const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext();
if (Src.empty())
return;
typename CHECK_CTX::CheckersTy::const_iterator
I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
if (I == E) {
Dst.insert(Src);
return;
}
ExplodedNodeSet Tmp1, Tmp2;
const ExplodedNodeSet *PrevSet = &Src;
for (; I != E; ++I) {
ExplodedNodeSet *CurrSet = 0;
if (I+1 == E)
CurrSet = &Dst;
else {
CurrSet = (PrevSet == &Tmp1) ? &Tmp2 : &Tmp1;
CurrSet->clear();
}
NodeBuilder B(*PrevSet, *CurrSet, BldrCtx);
for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
NI != NE; ++NI) {
checkCtx.runChecker(*I, B, *NI);
}
// If all the produced transitions are sinks, stop.
if (CurrSet->empty())
return;
// Update which NodeSet is the current one.
PrevSet = CurrSet;
}
}
示例2: 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);
}
}
示例3: HandleBlockEdge
void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) {
const CFGBlock *Blk = L.getDst();
// Check if we are entering the EXIT block.
if (Blk == &(L.getLocationContext()->getCFG()->getExit())) {
assert (L.getLocationContext()->getCFG()->getExit().size() == 0
&& "EXIT block cannot contain Stmts.");
// Process the final state transition.
EndOfFunctionNodeBuilder Builder(Blk, Pred, this);
SubEng.processEndOfFunction(Builder);
// This path is done. Don't enqueue any more nodes.
return;
}
// Call into the subengine to process entering the CFGBlock.
ExplodedNodeSet dstNodes;
BlockEntrance BE(Blk, Pred->getLocationContext());
GenericNodeBuilder<BlockEntrance> nodeBuilder(*this, Pred, BE);
SubEng.processCFGBlockEntrance(dstNodes, nodeBuilder);
if (dstNodes.empty()) {
if (!nodeBuilder.hasGeneratedNode) {
// Auto-generate a node and enqueue it to the worklist.
generateNode(BE, Pred->State, Pred);
}
}
else {
for (ExplodedNodeSet::iterator I = dstNodes.begin(), E = dstNodes.end();
I != E; ++I) {
WList->enqueue(*I);
}
}
for (SmallVectorImpl<ExplodedNode*>::const_iterator
I = nodeBuilder.sinks().begin(), E = nodeBuilder.sinks().end();
I != E; ++I) {
blocksExhausted.push_back(std::make_pair(L, *I));
}
}
示例4: evalOSAtomicCompareAndSwap
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);
//.........这里部分代码省略.........
示例5: 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);
}
示例6: VisitCXXConstructExpr
//.........这里部分代码省略.........
ExplodedNodeSet DstPreVisit;
getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this);
// FIXME: Is it possible and/or useful to do this before PreStmt?
ExplodedNodeSet PreInitialized;
{
StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
for (ExplodedNodeSet::iterator I = DstPreVisit.begin(),
E = DstPreVisit.end();
I != E; ++I) {
ProgramStateRef State = (*I)->getState();
if (CE->requiresZeroInitialization()) {
// 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->bindDefaultZero(Target, LCtx);
}
Bldr.generateNode(CE, *I, State, /*tag=*/nullptr,
ProgramPoint::PreStmtKind);
}
}
ExplodedNodeSet DstPreCall;
getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized,
*Call, *this);
ExplodedNodeSet DstEvaluated;
StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
if (CE->getConstructor()->isTrivial() &&
CE->getConstructor()->isCopyOrMoveConstructor() &&
!CallOpts.IsArrayCtorOrDtor) {
// FIXME: Handle other kinds of trivial constructors as well.
for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
I != E; ++I)
performTrivialCopy(Bldr, *I, *Call);
} else {
for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
I != E; ++I)
defaultEvalCall(Bldr, *I, *Call, CallOpts);
}
// If the CFG was constructed without elements for temporary destructors
// and the just-called constructor created a temporary object then
// stop exploration if the temporary object has a noreturn constructor.
// This can lose coverage because the destructor, if it were present
// in the CFG, would be called at the end of the full expression or
// later (for life-time extended temporaries) -- but avoids infeasible
// paths when no-return temporary destructors are used for assertions.
const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext();
if (!ADC->getCFGBuildOptions().AddTemporaryDtors) {
const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
if (Target && isa<CXXTempObjectRegion>(Target) &&
Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
// If we've inlined the constructor, then DstEvaluated would be empty.
// In this case we still want a sink, which could be implemented
// in processCallExit. But we don't have that implemented at the moment,
// so if you hit this assertion, see if you can avoid inlining
// the respective constructor when analyzer-config cfg-temporary-dtors
// is set to false.
// Otherwise there's nothing wrong with inlining such constructor.
assert(!DstEvaluated.empty() &&
"We should not have inlined this constructor!");
for (ExplodedNode *N : DstEvaluated) {
Bldr.generateSink(CE, N, N->getState());
}
// There is no need to run the PostCall and PostStmt checker
// callbacks because we just generated sinks on all nodes in th
// frontier.
return;
}
}
ExplodedNodeSet DstPostArgumentCleanup;
for (auto I : DstEvaluated)
finishArgumentConstruction(DstPostArgumentCleanup, I, *Call);
// If there were other constructors called for object-type arguments
// of this constructor, clean them up.
ExplodedNodeSet DstPostCall;
getCheckerManager().runCheckersForPostCall(DstPostCall,
DstPostArgumentCleanup,
*Call, *this);
getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this);
}