本文整理汇总了C++中ProgramStateRef::getSValAsScalarOrLoc方法的典型用法代码示例。如果您正苦于以下问题:C++ ProgramStateRef::getSValAsScalarOrLoc方法的具体用法?C++ ProgramStateRef::getSValAsScalarOrLoc怎么用?C++ ProgramStateRef::getSValAsScalarOrLoc使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ProgramStateRef
的用法示例。
在下文中一共展示了ProgramStateRef::getSValAsScalarOrLoc方法的5个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: trackNullOrUndefValue
bool bugreporter::trackNullOrUndefValue(const ExplodedNode *ErrorNode,
const Stmt *S,
BugReport &report, bool IsArg) {
if (!S || !ErrorNode)
return false;
if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S))
S = OVE->getSourceExpr();
const ExplodedNode *N = ErrorNode;
const Expr *Inner = 0;
if (const Expr *Ex = dyn_cast<Expr>(S)) {
Ex = Ex->IgnoreParenCasts();
if (ExplodedGraph::isInterestingLValueExpr(Ex) || CallEvent::isCallStmt(Ex))
Inner = Ex;
}
if (IsArg) {
assert(N->getLocation().getAs<CallEnter>() && "Tracking arg but not at call");
} else {
// Walk through nodes until we get one that matches the statement exactly.
// Alternately, if we hit a known lvalue for the statement, we know we've
// gone too far (though we can likely track the lvalue better anyway).
do {
const ProgramPoint &pp = N->getLocation();
if (Optional<PostStmt> ps = pp.getAs<PostStmt>()) {
if (ps->getStmt() == S || ps->getStmt() == Inner)
break;
} else if (Optional<CallExitEnd> CEE = pp.getAs<CallExitEnd>()) {
if (CEE->getCalleeContext()->getCallSite() == S ||
CEE->getCalleeContext()->getCallSite() == Inner)
break;
}
N = N->getFirstPred();
} while (N);
if (!N)
return false;
}
ProgramStateRef state = N->getState();
// See if the expression we're interested refers to a variable.
// If so, we can track both its contents and constraints on its value.
if (Inner && ExplodedGraph::isInterestingLValueExpr(Inner)) {
const MemRegion *R = 0;
// First check if this is a DeclRefExpr for a C++ reference type.
// For those, we want the location of the reference.
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Inner)) {
if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
if (VD->getType()->isReferenceType()) {
ProgramStateManager &StateMgr = state->getStateManager();
MemRegionManager &MRMgr = StateMgr.getRegionManager();
R = MRMgr.getVarRegion(VD, N->getLocationContext());
}
}
}
// For all other cases, find the location by scouring the ExplodedGraph.
if (!R) {
// Find the ExplodedNode where the lvalue (the value of 'Ex')
// was computed. We need this for getting the location value.
const ExplodedNode *LVNode = N;
while (LVNode) {
if (Optional<PostStmt> P = LVNode->getLocation().getAs<PostStmt>()) {
if (P->getStmt() == Inner)
break;
}
LVNode = LVNode->getFirstPred();
}
assert(LVNode && "Unable to find the lvalue node.");
ProgramStateRef LVState = LVNode->getState();
R = LVState->getSVal(Inner, LVNode->getLocationContext()).getAsRegion();
}
if (R) {
// Mark both the variable region and its contents as interesting.
SVal V = state->getRawSVal(loc::MemRegionVal(R));
// If the value matches the default for the variable region, that
// might mean that it's been cleared out of the state. Fall back to
// the full argument expression (with casts and such intact).
if (IsArg) {
bool UseArgValue = V.isUnknownOrUndef() || V.isZeroConstant();
if (!UseArgValue) {
const SymbolRegionValue *SRV =
dyn_cast_or_null<SymbolRegionValue>(V.getAsLocSymbol());
if (SRV)
UseArgValue = (SRV->getRegion() == R);
}
if (UseArgValue)
V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
}
report.markInteresting(R);
report.markInteresting(V);
report.addVisitor(new UndefOrNullArgVisitor(R));
//.........这里部分代码省略.........
示例2: trackNullOrUndefValue
bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
BugReport &report, bool IsArg) {
if (!S || !N)
return false;
if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S))
S = OVE->getSourceExpr();
if (IsArg) {
assert(isa<CallEnter>(N->getLocation()) && "Tracking arg but not at call");
} else {
// Walk through nodes until we get one that matches the statement exactly.
do {
const ProgramPoint &pp = N->getLocation();
if (const PostStmt *ps = dyn_cast<PostStmt>(&pp)) {
if (ps->getStmt() == S)
break;
} else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&pp)) {
if (CEE->getCalleeContext()->getCallSite() == S)
break;
}
N = N->getFirstPred();
} while (N);
if (!N)
return false;
}
ProgramStateRef state = N->getState();
// See if the expression we're interested refers to a variable.
// If so, we can track both its contents and constraints on its value.
if (const Expr *Ex = dyn_cast<Expr>(S)) {
// Strip off parens and casts. Note that this will never have issues with
// C++ user-defined implicit conversions, because those have a constructor
// or function call inside.
Ex = Ex->IgnoreParenCasts();
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
// FIXME: Right now we only track VarDecls because it's non-trivial to
// get a MemRegion for any other DeclRefExprs. <rdar://problem/12114812>
if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
ProgramStateManager &StateMgr = state->getStateManager();
MemRegionManager &MRMgr = StateMgr.getRegionManager();
const VarRegion *R = MRMgr.getVarRegion(VD, N->getLocationContext());
// Mark both the variable region and its contents as interesting.
SVal V = state->getRawSVal(loc::MemRegionVal(R));
// If the value matches the default for the variable region, that
// might mean that it's been cleared out of the state. Fall back to
// the full argument expression (with casts and such intact).
if (IsArg) {
bool UseArgValue = V.isUnknownOrUndef() || V.isZeroConstant();
if (!UseArgValue) {
const SymbolRegionValue *SRV =
dyn_cast_or_null<SymbolRegionValue>(V.getAsLocSymbol());
if (SRV)
UseArgValue = (SRV->getRegion() == R);
}
if (UseArgValue)
V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
}
report.markInteresting(R);
report.markInteresting(V);
report.addVisitor(new UndefOrNullArgVisitor(R));
// If the contents are symbolic, find out when they became null.
if (V.getAsLocSymbol()) {
BugReporterVisitor *ConstraintTracker
= new TrackConstraintBRVisitor(cast<DefinedSVal>(V), false);
report.addVisitor(ConstraintTracker);
}
report.addVisitor(new FindLastStoreBRVisitor(V, R));
return true;
}
}
}
// If the expression does NOT refer to a variable, we can still track
// constraints on its contents.
SVal V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
// Uncomment this to find cases where we aren't properly getting the
// base value that was dereferenced.
// assert(!V.isUnknownOrUndef());
// Is it a symbolic value?
if (loc::MemRegionVal *L = dyn_cast<loc::MemRegionVal>(&V)) {
// At this point we are dealing with the region's LValue.
// However, if the rvalue is a symbolic region, we should track it as well.
SVal RVal = state->getSVal(L->getRegion());
const MemRegion *RegionRVal = RVal.getAsRegion();
report.addVisitor(new UndefOrNullArgVisitor(L->getRegion()));
if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) {
report.markInteresting(RegionRVal);
report.addVisitor(new TrackConstraintBRVisitor(
//.........这里部分代码省略.........
示例3: os
std::shared_ptr<PathDiagnosticPiece>
RefCountReportVisitor::VisitNode(const ExplodedNode *N,
BugReporterContext &BRC, BugReport &BR) {
const SourceManager &SM = BRC.getSourceManager();
CallEventManager &CEMgr = BRC.getStateManager().getCallEventManager();
if (auto CE = N->getLocationAs<CallExitBegin>())
if (auto PD = annotateConsumedSummaryMismatch(N, *CE, SM, CEMgr))
return PD;
// FIXME: We will eventually need to handle non-statement-based events
// (__attribute__((cleanup))).
if (!N->getLocation().getAs<StmtPoint>())
return nullptr;
// Check if the type state has changed.
const ExplodedNode *PrevNode = N->getFirstPred();
ProgramStateRef PrevSt = PrevNode->getState();
ProgramStateRef CurrSt = N->getState();
const LocationContext *LCtx = N->getLocationContext();
const RefVal* CurrT = getRefBinding(CurrSt, Sym);
if (!CurrT) return nullptr;
const RefVal &CurrV = *CurrT;
const RefVal *PrevT = getRefBinding(PrevSt, Sym);
// Create a string buffer to constain all the useful things we want
// to tell the user.
std::string sbuf;
llvm::raw_string_ostream os(sbuf);
// This is the allocation site since the previous node had no bindings
// for this symbol.
if (!PrevT) {
const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
if (isa<ObjCIvarRefExpr>(S) &&
isSynthesizedAccessor(LCtx->getStackFrame())) {
S = LCtx->getStackFrame()->getCallSite();
}
if (isa<ObjCArrayLiteral>(S)) {
os << "NSArray literal is an object with a +0 retain count";
} else if (isa<ObjCDictionaryLiteral>(S)) {
os << "NSDictionary literal is an object with a +0 retain count";
} else if (const ObjCBoxedExpr *BL = dyn_cast<ObjCBoxedExpr>(S)) {
if (isNumericLiteralExpression(BL->getSubExpr()))
os << "NSNumber literal is an object with a +0 retain count";
else {
const ObjCInterfaceDecl *BoxClass = nullptr;
if (const ObjCMethodDecl *Method = BL->getBoxingMethod())
BoxClass = Method->getClassInterface();
// We should always be able to find the boxing class interface,
// but consider this future-proofing.
if (BoxClass) {
os << *BoxClass << " b";
} else {
os << "B";
}
os << "oxed expression produces an object with a +0 retain count";
}
} else if (isa<ObjCIvarRefExpr>(S)) {
os << "Object loaded from instance variable";
} else {
generateDiagnosticsForCallLike(CurrSt, LCtx, CurrV, Sym, S, os);
}
PathDiagnosticLocation Pos(S, SM, N->getLocationContext());
return std::make_shared<PathDiagnosticEventPiece>(Pos, os.str());
}
// Gather up the effects that were performed on the object at this
// program point
bool DeallocSent = false;
if (N->getLocation().getTag() &&
N->getLocation().getTag()->getTagDescription().contains(
RetainCountChecker::DeallocTagDescription)) {
// We only have summaries attached to nodes after evaluating CallExpr and
// ObjCMessageExprs.
const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
// Iterate through the parameter expressions and see if the symbol
// was ever passed as an argument.
unsigned i = 0;
for (auto AI=CE->arg_begin(), AE=CE->arg_end(); AI!=AE; ++AI, ++i) {
// Retrieve the value of the argument. Is it the symbol
// we are interested in?
if (CurrSt->getSValAsScalarOrLoc(*AI, LCtx).getAsLocSymbol() != Sym)
continue;
// We have an argument. Get the effect!
DeallocSent = true;
}
//.........这里部分代码省略.........
示例4: trackNullOrUndefValue
void bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
BugReport &report) {
if (!S || !N)
return;
ProgramStateManager &StateMgr = N->getState()->getStateManager();
// Walk through nodes until we get one that matches the statement exactly.
while (N) {
const ProgramPoint &pp = N->getLocation();
if (const PostStmt *ps = dyn_cast<PostStmt>(&pp)) {
if (ps->getStmt() == S)
break;
} else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&pp)) {
if (CEE->getCalleeContext()->getCallSite() == S)
break;
}
N = N->getFirstPred();
}
if (!N)
return;
ProgramStateRef state = N->getState();
// See if the expression we're interested refers to a variable.
// If so, we can track both its contents and constraints on its value.
if (const Expr *Ex = dyn_cast<Expr>(S)) {
// Strip off parens and casts. Note that this will never have issues with
// C++ user-defined implicit conversions, because those have a constructor
// or function call inside.
Ex = Ex->IgnoreParenCasts();
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
// FIXME: Right now we only track VarDecls because it's non-trivial to
// get a MemRegion for any other DeclRefExprs. <rdar://problem/12114812>
if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
const VarRegion *R =
StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
// Mark both the variable region and its contents as interesting.
SVal V = state->getRawSVal(loc::MemRegionVal(R));
report.markInteresting(R);
report.markInteresting(V);
// If the contents are symbolic, find out when they became null.
if (V.getAsLocSymbol()) {
BugReporterVisitor *ConstraintTracker
= new TrackConstraintBRVisitor(cast<loc::MemRegionVal>(V), false);
report.addVisitor(ConstraintTracker);
}
report.addVisitor(new FindLastStoreBRVisitor(V, R));
return;
}
}
}
// If the expression does NOT refer to a variable, we can still track
// constraints on its contents.
SVal V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
// Uncomment this to find cases where we aren't properly getting the
// base value that was dereferenced.
// assert(!V.isUnknownOrUndef());
// Is it a symbolic value?
if (loc::MemRegionVal *L = dyn_cast<loc::MemRegionVal>(&V)) {
const MemRegion *Base = L->getRegion()->getBaseRegion();
if (isa<SymbolicRegion>(Base)) {
report.markInteresting(Base);
report.addVisitor(new TrackConstraintBRVisitor(loc::MemRegionVal(Base),
false));
}
} else {
// Otherwise, if the value came from an inlined function call,
// we should at least make sure that function isn't pruned in our output.
ReturnVisitor::addVisitorIfNecessary(N, S, report);
}
}
示例5: generateDiagnosticsForCallLike
static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt,
const LocationContext *LCtx,
const RefVal &CurrV, SymbolRef &Sym,
const Stmt *S,
llvm::raw_string_ostream &os) {
CallEventManager &Mgr = CurrSt->getStateManager().getCallEventManager();
if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
// Get the name of the callee (if it is available)
// from the tracked SVal.
SVal X = CurrSt->getSValAsScalarOrLoc(CE->getCallee(), LCtx);
const FunctionDecl *FD = X.getAsFunctionDecl();
// If failed, try to get it from AST.
if (!FD)
FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
if (const auto *MD = dyn_cast<CXXMethodDecl>(CE->getCalleeDecl())) {
os << "Call to method '" << MD->getQualifiedNameAsString() << '\'';
} else if (FD) {
os << "Call to function '" << FD->getQualifiedNameAsString() << '\'';
} else {
os << "function call";
}
} else if (isa<CXXNewExpr>(S)) {
os << "Operator 'new'";
} else {
assert(isa<ObjCMessageExpr>(S));
CallEventRef<ObjCMethodCall> Call =
Mgr.getObjCMethodCall(cast<ObjCMessageExpr>(S), CurrSt, LCtx);
switch (Call->getMessageKind()) {
case OCM_Message:
os << "Method";
break;
case OCM_PropertyAccess:
os << "Property";
break;
case OCM_Subscript:
os << "Subscript";
break;
}
}
Optional<CallEventRef<>> CE = Mgr.getCall(S, CurrSt, LCtx);
auto Idx = findArgIdxOfSymbol(CurrSt, LCtx, Sym, CE);
// If index is not found, we assume that the symbol was returned.
if (!Idx) {
os << " returns ";
} else {
os << " writes ";
}
if (CurrV.getObjKind() == ObjKind::CF) {
os << "a Core Foundation object of type '"
<< Sym->getType().getAsString() << "' with a ";
} else if (CurrV.getObjKind() == ObjKind::OS) {
os << "an OSObject of type '" << getPrettyTypeName(Sym->getType())
<< "' with a ";
} else if (CurrV.getObjKind() == ObjKind::Generalized) {
os << "an object of type '" << Sym->getType().getAsString()
<< "' with a ";
} else {
assert(CurrV.getObjKind() == ObjKind::ObjC);
QualType T = Sym->getType();
if (!isa<ObjCObjectPointerType>(T)) {
os << "an Objective-C object with a ";
} else {
const ObjCObjectPointerType *PT = cast<ObjCObjectPointerType>(T);
os << "an instance of " << PT->getPointeeType().getAsString()
<< " with a ";
}
}
if (CurrV.isOwned()) {
os << "+1 retain count";
} else {
assert(CurrV.isNotOwned());
os << "+0 retain count";
}
if (Idx) {
os << " into an out parameter '";
const ParmVarDecl *PVD = (*CE)->parameters()[*Idx];
PVD->getNameForDiagnostic(os, PVD->getASTContext().getPrintingPolicy(),
/*Qualified=*/false);
os << "'";
QualType RT = (*CE)->getResultType();
if (!RT.isNull() && !RT->isVoidType()) {
SVal RV = (*CE)->getReturnValue();
if (CurrSt->isNull(RV).isConstrainedTrue()) {
os << " (assuming the call returns zero)";
} else if (CurrSt->isNonNull(RV).isConstrainedTrue()) {
os << " (assuming the call returns non-zero)";
}
}
}
}