本文整理汇总了C++中ProgramStateRef::BindExpr方法的典型用法代码示例。如果您正苦于以下问题:C++ ProgramStateRef::BindExpr方法的具体用法?C++ ProgramStateRef::BindExpr怎么用?C++ ProgramStateRef::BindExpr使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ProgramStateRef
的用法示例。
在下文中一共展示了ProgramStateRef::BindExpr方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: VisitCompoundLiteralExpr
void ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
const InitListExpr *ILE
= cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
ProgramStateRef state = Pred->getState();
SVal ILV = state->getSVal(ILE, Pred->getLocationContext());
const LocationContext *LC = Pred->getLocationContext();
state = state->bindCompoundLiteral(CL, LC, ILV);
// Compound literal expressions are a GNU extension in C++.
// Unlike in C, where CLs are lvalues, in C++ CLs are prvalues,
// and like temporary objects created by the functional notation T()
// CLs are destroyed at the end of the containing full-expression.
// HOWEVER, an rvalue of array type is not something the analyzer can
// reason about, since we expect all regions to be wrapped in Locs.
// So we treat array CLs as lvalues as well, knowing that they will decay
// to pointers as soon as they are used.
if (CL->isGLValue() || CL->getType()->isArrayType())
B.generateNode(CL, Pred, state->BindExpr(CL, LC, state->getLValue(CL, LC)));
else
B.generateNode(CL, Pred, state->BindExpr(CL, LC, ILV));
}
示例2: bindReturnValue
ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
const LocationContext *LCtx,
ProgramStateRef State) {
const Expr *E = Call.getOriginExpr();
if (!E)
return State;
// Some method families have known return values.
if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(&Call)) {
switch (Msg->getMethodFamily()) {
default:
break;
case OMF_autorelease:
case OMF_retain:
case OMF_self: {
// These methods return their receivers.
return State->BindExpr(E, LCtx, Msg->getReceiverSVal());
}
}
} else if (const CXXConstructorCall *C = dyn_cast<CXXConstructorCall>(&Call)){
return State->BindExpr(E, LCtx, C->getCXXThisVal());
}
// Conjure a symbol if the return value is unknown.
QualType ResultTy = Call.getResultType();
SValBuilder &SVB = getSValBuilder();
unsigned Count = currBldrCtx->blockCount();
SVal R = SVB.conjureSymbolVal(0, E, LCtx, ResultTy, Count);
return State->BindExpr(E, LCtx, R);
}
示例3: HandleNilReceiver
void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
ProgramStateRef state,
const ObjCMethodCall &Msg) const {
ASTContext &Ctx = C.getASTContext();
static CheckerProgramPointTag Tag(this, "NilReceiver");
// Check the return type of the message expression. A message to nil will
// return different values depending on the return type and the architecture.
QualType RetTy = Msg.getResultType();
CanQualType CanRetTy = Ctx.getCanonicalType(RetTy);
const LocationContext *LCtx = C.getLocationContext();
if (CanRetTy->isStructureOrClassType()) {
// Structure returns are safe since the compiler zeroes them out.
SVal V = C.getSValBuilder().makeZeroVal(RetTy);
C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V), &Tag);
return;
}
// Other cases: check if sizeof(return type) > sizeof(void*)
if (CanRetTy != Ctx.VoidTy && C.getLocationContext()->getParentMap()
.isConsumedExpr(Msg.getOriginExpr())) {
// Compute: sizeof(void *) and sizeof(return type)
const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy);
if (CanRetTy.getTypePtr()->isReferenceType()||
(voidPtrSize < returnTypeSize &&
!(supportsNilWithFloatRet(Ctx.getTargetInfo().getTriple()) &&
(Ctx.FloatTy == CanRetTy ||
Ctx.DoubleTy == CanRetTy ||
Ctx.LongDoubleTy == CanRetTy ||
Ctx.LongLongTy == CanRetTy ||
Ctx.UnsignedLongLongTy == CanRetTy)))) {
if (ExplodedNode *N = C.generateSink(state, nullptr, &Tag))
emitNilReceiverBug(C, Msg, N);
return;
}
// Handle the safe cases where the return value is 0 if the
// receiver is nil.
//
// FIXME: For now take the conservative approach that we only
// return null values if we *know* that the receiver is nil.
// This is because we can have surprises like:
//
// ... = [[NSScreens screens] objectAtIndex:0];
//
// What can happen is that [... screens] could return nil, but
// it most likely isn't nil. We should assume the semantics
// of this case unless we have *a lot* more knowledge.
//
SVal V = C.getSValBuilder().makeZeroVal(RetTy);
C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V), &Tag);
return;
}
C.addTransition(state);
}
示例4: processCallExit
void ExprEngine::processCallExit(ExplodedNode *Pred) {
ProgramStateRef state = Pred->getState();
const StackFrameContext *calleeCtx =
Pred->getLocationContext()->getCurrentStackFrame();
const LocationContext *callerCtx = calleeCtx->getParent();
const Stmt *CE = calleeCtx->getCallSite();
// If the callee returns an expression, bind its value to CallExpr.
if (const ReturnStmt *RS = getReturnStmt(Pred)) {
const LocationContext *LCtx = Pred->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, Pred->getLocationContext(), ThisV);
}
static SimpleProgramPointTag returnTag("ExprEngine : Call Return");
PostStmt Loc(CE, callerCtx, &returnTag);
bool isNew;
ExplodedNode *N = G.getNode(Loc, state, false, &isNew);
N->addPredecessor(Pred, G);
if (!isNew)
return;
// Perform the post-condition check of the CallExpr.
ExplodedNodeSet Dst;
NodeBuilderContext Ctx(Engine, calleeCtx->getCallSiteBlock(), N);
SaveAndRestore<const NodeBuilderContext*> NBCSave(currentBuilderContext,
&Ctx);
SaveAndRestore<unsigned> CBISave(currentStmtIdx, calleeCtx->getIndex());
getCheckerManager().runCheckersForPostStmt(Dst, N, CE, *this,
/* wasInlined */ true);
// Enqueue the next element in the block.
for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end(); I != E; ++I) {
Engine.getWorkList()->enqueue(*I,
calleeCtx->getCallSiteBlock(),
calleeCtx->getIndex()+1);
}
}
示例5: bindReturnValue
ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
const LocationContext *LCtx,
ProgramStateRef State) {
const Expr *E = Call.getOriginExpr();
if (!E)
return State;
// Some method families have known return values.
if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(&Call)) {
switch (Msg->getMethodFamily()) {
default:
break;
case OMF_autorelease:
case OMF_retain:
case OMF_self: {
// These methods return their receivers.
return State->BindExpr(E, LCtx, Msg->getReceiverSVal());
}
}
} else if (const CXXConstructorCall *C = dyn_cast<CXXConstructorCall>(&Call)){
SVal ThisV = C->getCXXThisVal();
// If the constructed object is a temporary prvalue, get its bindings.
if (isTemporaryPRValue(cast<CXXConstructExpr>(E), ThisV))
ThisV = State->getSVal(ThisV.castAs<Loc>());
return State->BindExpr(E, LCtx, ThisV);
}
// Conjure a symbol if the return value is unknown.
QualType ResultTy = Call.getResultType();
SValBuilder &SVB = getSValBuilder();
unsigned Count = currBldrCtx->blockCount();
// See if we need to conjure a heap pointer instead of
// a regular unknown pointer.
bool IsHeapPointer = false;
if (const auto *CNE = dyn_cast<CXXNewExpr>(E))
if (CNE->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
// FIXME: Delegate this to evalCall in MallocChecker?
IsHeapPointer = true;
}
SVal R = IsHeapPointer
? SVB.getConjuredHeapSymbolVal(E, LCtx, Count)
: SVB.conjureSymbolVal(nullptr, E, LCtx, ResultTy, Count);
return State->BindExpr(E, LCtx, R);
}
示例6: evalCall
bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
CheckerContext &C) const {
ProgramStateRef state = C.getState();
const FunctionDecl *FD = C.getCalleeDecl(CE);
const LocationContext *LCtx = C.getLocationContext();
if (!FD)
return false;
unsigned id = FD->getBuiltinID();
if (!id)
return false;
switch (id) {
case Builtin::BI__builtin_expect: {
// For __builtin_expect, just return the value of the subexpression.
assert (CE->arg_begin() != CE->arg_end());
SVal X = state->getSVal(*(CE->arg_begin()), LCtx);
C.addTransition(state->BindExpr(CE, LCtx, X));
return true;
}
case Builtin::BI__builtin_alloca: {
// FIXME: Refactor into StoreManager itself?
MemRegionManager& RM = C.getStoreManager().getRegionManager();
const AllocaRegion* R =
RM.getAllocaRegion(CE, C.blockCount(), C.getLocationContext());
// Set the extent of the region in bytes. This enables us to use the
// SVal of the argument directly. If we save the extent in bits, we
// cannot represent values like symbol*8.
DefinedOrUnknownSVal Size =
state->getSVal(*(CE->arg_begin()), LCtx).castAs<DefinedOrUnknownSVal>();
SValBuilder& svalBuilder = C.getSValBuilder();
DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
DefinedOrUnknownSVal extentMatchesSizeArg =
svalBuilder.evalEQ(state, Extent, Size);
state = state->assume(extentMatchesSizeArg, true);
assert(state && "The region should not have any previous constraints");
C.addTransition(state->BindExpr(CE, LCtx, loc::MemRegionVal(R)));
return true;
}
}
return false;
}
示例7: VisitInitListExpr
void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
ProgramStateRef state = Pred->getState();
const LocationContext *LCtx = Pred->getLocationContext();
QualType T = getContext().getCanonicalType(IE->getType());
unsigned NumInitElements = IE->getNumInits();
if (!IE->isGLValue() &&
(T->isArrayType() || T->isRecordType() || T->isVectorType() ||
T->isAnyComplexType())) {
llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
// Handle base case where the initializer has no elements.
// e.g: static int* myArray[] = {};
if (NumInitElements == 0) {
SVal V = svalBuilder.makeCompoundVal(T, vals);
B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
return;
}
for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
ei = IE->rend(); it != ei; ++it) {
SVal V = state->getSVal(cast<Expr>(*it), LCtx);
vals = getBasicVals().prependSVal(V, vals);
}
B.generateNode(IE, Pred,
state->BindExpr(IE, LCtx,
svalBuilder.makeCompoundVal(T, vals)));
return;
}
// Handle scalars: int{5} and int{} and GLvalues.
// Note, if the InitListExpr is a GLvalue, it means that there is an address
// representing it, so it must have a single init element.
assert(NumInitElements <= 1);
SVal V;
if (NumInitElements == 0)
V = getSValBuilder().makeZeroVal(T);
else
V = state->getSVal(IE->getInit(0), LCtx);
B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
}
示例8: defaultEvalCall
void ExprEngine::defaultEvalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
const CallEvent &Call) {
// Try to inline the call.
ProgramStateRef state = 0;
const Expr *E = Call.getOriginExpr();
if (E) {
state = getInlineFailedState(Pred, E);
if (state == 0 && inlineCall(Dst, Call, Pred))
return;
}
// If we can't inline it, handle the return value and invalidate the regions.
StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
// Invalidate any regions touched by the call.
unsigned Count = currentBuilderContext->getCurrentBlockCount();
if (state == 0)
state = Pred->getState();
state = Call.invalidateRegions(Count, state);
// Conjure a symbol value to use as the result.
assert(Call.getOriginExpr() && "Must have an expression to bind the result");
QualType ResultTy = Call.getResultType();
SValBuilder &SVB = getSValBuilder();
const LocationContext *LCtx = Pred->getLocationContext();
SVal RetVal = SVB.getConjuredSymbolVal(0, Call.getOriginExpr(), LCtx,
ResultTy, Count);
// And make the result node.
state = state->BindExpr(Call.getOriginExpr(), LCtx, RetVal);
Bldr.generateNode(Call.getOriginExpr(), Pred, state);
}
示例9: OpenFileAux
void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) const {
ProgramStateRef state = C.getState();
SValBuilder &svalBuilder = C.getSValBuilder();
const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
DefinedSVal RetVal = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx,
C.blockCount())
.castAs<DefinedSVal>();
state = state->BindExpr(CE, C.getLocationContext(), RetVal);
ConstraintManager &CM = C.getConstraintManager();
// Bifurcate the state into two: one with a valid FILE* pointer, the other
// with a NULL.
ProgramStateRef stateNotNull, stateNull;
std::tie(stateNotNull, stateNull) = CM.assumeDual(state, RetVal);
if (SymbolRef Sym = RetVal.getAsSymbol()) {
// if RetVal is not NULL, set the symbol's state to Opened.
stateNotNull =
stateNotNull->set<StreamMap>(Sym,StreamState::getOpened(CE));
stateNull =
stateNull->set<StreamMap>(Sym, StreamState::getOpenFailed(CE));
C.addTransition(stateNotNull);
C.addTransition(stateNull);
}
}
示例10: defaultEvalCall
void ExprEngine::defaultEvalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
const CallEvent &Call) {
// Try to inline the call.
// The origin expression here is just used as a kind of checksum;
// for CallEvents that do not have origin expressions, this should still be
// safe.
const Expr *E = Call.getOriginExpr();
ProgramStateRef state = getInlineFailedState(Pred, E);
if (state == 0 && inlineCall(Dst, Call, Pred))
return;
// If we can't inline it, handle the return value and invalidate the regions.
NodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
// Invalidate any regions touched by the call.
unsigned Count = currentBuilderContext->getCurrentBlockCount();
if (state == 0)
state = Pred->getState();
state = Call.invalidateRegions(Count, state);
// Conjure a symbol value to use as the result.
if (E) {
QualType ResultTy = Call.getResultType();
SValBuilder &SVB = getSValBuilder();
const LocationContext *LCtx = Pred->getLocationContext();
SVal RetVal = SVB.getConjuredSymbolVal(0, E, LCtx, ResultTy, Count);
state = state->BindExpr(E, LCtx, RetVal);
}
// And make the result node.
Bldr.generateNode(Call.getProgramPoint(), state, Pred);
}
示例11: CreateCXXTemporaryObject
void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens();
ProgramStateRef state = Pred->getState();
const LocationContext *LCtx = Pred->getLocationContext();
// Bind the temporary object to the value of the expression. Then bind
// the expression to the location of the object.
SVal V = state->getSVal(tempExpr, LCtx);
// If the value is already a CXXTempObjectRegion, it is fine as it is.
// Otherwise, create a new CXXTempObjectRegion, and copy the value into it.
const MemRegion *MR = V.getAsRegion();
if (!MR || !isa<CXXTempObjectRegion>(MR)) {
const MemRegion *R =
svalBuilder.getRegionManager().getCXXTempObjectRegion(ME, LCtx);
SVal L = loc::MemRegionVal(R);
state = state->bindLoc(L, V);
V = L;
}
Bldr.generateNode(ME, Pred, state->BindExpr(ME, LCtx, V));
}
示例12: Bldr
void ExprEngine::
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
QualType T = Ex->getTypeOfArgument();
if (Ex->getKind() == UETT_SizeOf) {
if (!T->isIncompleteType() && !T->isConstantSizeType()) {
assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
// FIXME: Add support for VLA type arguments and VLA expressions.
// When that happens, we should probably refactor VLASizeChecker's code.
return;
}
else if (T->getAs<ObjCObjectType>()) {
// Some code tries to take the sizeof an ObjCObjectType, relying that
// the compiler has laid out its representation. Just report Unknown
// for these.
return;
}
}
APSInt Value = Ex->EvaluateKnownConstInt(getContext());
CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
ProgramStateRef state = Pred->getState();
state = state->BindExpr(Ex, Pred->getLocationContext(),
svalBuilder.makeIntVal(amt.getQuantity(),
Ex->getType()));
Bldr.generateNode(Ex, Pred, state);
}
示例13: CreateCXXTemporaryObject
void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens();
ProgramStateRef state = Pred->getState();
const LocationContext *LCtx = Pred->getLocationContext();
// Bind the temporary object to the value of the expression. Then bind
// the expression to the location of the object.
SVal V = state->getSVal(tempExpr, LCtx);
// If the object is a record, the constructor will have already created
// a temporary object region. If it is not, we need to copy the value over.
if (!ME->getType()->isRecordType()) {
const MemRegion *R =
svalBuilder.getRegionManager().getCXXTempObjectRegion(ME, LCtx);
SVal L = loc::MemRegionVal(R);
state = state->bindLoc(L, V);
V = L;
}
Bldr.generateNode(ME, Pred, state->BindExpr(ME, LCtx, V));
}
示例14: VisitCompoundLiteralExpr
void ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
ProgramStateRef State = Pred->getState();
const LocationContext *LCtx = Pred->getLocationContext();
const Expr *Init = CL->getInitializer();
SVal V = State->getSVal(CL->getInitializer(), LCtx);
if (isa<CXXConstructExpr>(Init)) {
// No work needed. Just pass the value up to this expression.
} else {
assert(isa<InitListExpr>(Init));
Loc CLLoc = State->getLValue(CL, LCtx);
State = State->bindLoc(CLLoc, V);
// Compound literal expressions are a GNU extension in C++.
// Unlike in C, where CLs are lvalues, in C++ CLs are prvalues,
// and like temporary objects created by the functional notation T()
// CLs are destroyed at the end of the containing full-expression.
// HOWEVER, an rvalue of array type is not something the analyzer can
// reason about, since we expect all regions to be wrapped in Locs.
// So we treat array CLs as lvalues as well, knowing that they will decay
// to pointers as soon as they are used.
if (CL->isGLValue() || CL->getType()->isArrayType())
V = CLLoc;
}
B.generateNode(CL, Pred, State->BindExpr(CL, LCtx, V));
}
示例15: VisitGuardedExpr
void ExprEngine::VisitGuardedExpr(const Expr *Ex,
const Expr *L,
const Expr *R,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
assert(L && R);
StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
ProgramStateRef state = Pred->getState();
const LocationContext *LCtx = Pred->getLocationContext();
const CFGBlock *SrcBlock = 0;
// Find the predecessor block.
ProgramStateRef SrcState = state;
for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
ProgramPoint PP = N->getLocation();
if (PP.getAs<PreStmtPurgeDeadSymbols>() || PP.getAs<BlockEntrance>()) {
assert(N->pred_size() == 1);
continue;
}
SrcBlock = PP.castAs<BlockEdge>().getSrc();
SrcState = N->getState();
break;
}
assert(SrcBlock && "missing function entry");
// Find the last expression in the predecessor block. That is the
// expression that is used for the value of the ternary expression.
bool hasValue = false;
SVal V;
for (CFGBlock::const_reverse_iterator I = SrcBlock->rbegin(),
E = SrcBlock->rend(); I != E; ++I) {
CFGElement CE = *I;
if (Optional<CFGStmt> CS = CE.getAs<CFGStmt>()) {
const Expr *ValEx = cast<Expr>(CS->getStmt());
ValEx = ValEx->IgnoreParens();
// For GNU extension '?:' operator, the left hand side will be an
// OpaqueValueExpr, so get the underlying expression.
if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L))
L = OpaqueEx->getSourceExpr();
// If the last expression in the predecessor block matches true or false
// subexpression, get its the value.
if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()) {
hasValue = true;
V = SrcState->getSVal(ValEx, LCtx);
}
break;
}
}
if (!hasValue)
V = svalBuilder.conjureSymbolVal(0, Ex, LCtx, currBldrCtx->blockCount());
// Generate a new node with the binding from the appropriate path.
B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true));
}