本文整理汇总了C++中CheckerContext::getLocationContext方法的典型用法代码示例。如果您正苦于以下问题:C++ CheckerContext::getLocationContext方法的具体用法?C++ CheckerContext::getLocationContext怎么用?C++ CheckerContext::getLocationContext使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CheckerContext
的用法示例。
在下文中一共展示了CheckerContext::getLocationContext方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: assumeExprIsNonNull
static ProgramStateRef assumeExprIsNonNull(const Expr *NonNullExpr,
ProgramStateRef State,
CheckerContext &C) {
SVal Val = State->getSVal(NonNullExpr, C.getLocationContext());
if (Optional<DefinedOrUnknownSVal> DV = Val.getAs<DefinedOrUnknownSVal>())
return State->assume(*DV, true);
return State;
}
示例2: checkBind
void UndefinedAssignmentChecker::checkBind(SVal location, SVal val,
const Stmt *StoreE,
CheckerContext &C) const {
if (!val.isUndef())
return;
// Do not report assignments of uninitialized values inside swap functions.
// This should allow to swap partially uninitialized structs
// (radar://14129997)
if (const FunctionDecl *EnclosingFunctionDecl =
dyn_cast<FunctionDecl>(C.getStackFrame()->getDecl()))
if (C.getCalleeName(EnclosingFunctionDecl) == "swap")
return;
ExplodedNode *N = C.generateSink();
if (!N)
return;
const char *str = "Assigned value is garbage or undefined";
if (!BT)
BT.reset(new BuiltinBug(str));
// Generate a report for this bug.
const Expr *ex = 0;
while (StoreE) {
if (const BinaryOperator *B = dyn_cast<BinaryOperator>(StoreE)) {
if (B->isCompoundAssignmentOp()) {
ProgramStateRef state = C.getState();
if (state->getSVal(B->getLHS(), C.getLocationContext()).isUndef()) {
str = "The left expression of the compound assignment is an "
"uninitialized value. The computed value will also be garbage";
ex = B->getLHS();
break;
}
}
ex = B->getRHS();
break;
}
if (const DeclStmt *DS = dyn_cast<DeclStmt>(StoreE)) {
const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
ex = VD->getInit();
}
break;
}
BugReport *R = new BugReport(*BT, str, N);
if (ex) {
R->addRange(ex->getSourceRange());
bugreporter::trackNullOrUndefValue(N, ex, *R);
}
C.emitReport(R);
}
示例3: checkPostStmt
void MacOSKeychainAPIChecker::checkPostStmt(const CallExpr *CE,
CheckerContext &C) const {
ProgramStateRef State = C.getState();
const FunctionDecl *FD = C.getCalleeDecl(CE);
if (!FD || FD->getKind() != Decl::Function)
return;
StringRef funName = C.getCalleeName(FD);
// If a value has been allocated, add it to the set for tracking.
unsigned idx = getTrackedFunctionIndex(funName, true);
if (idx == InvalidIdx)
return;
const Expr *ArgExpr = CE->getArg(FunctionsToTrack[idx].Param);
// If the argument entered as an enclosing function parameter, skip it to
// avoid false positives.
if (isEnclosingFunctionParam(ArgExpr) &&
C.getLocationContext()->getParent() == 0)
return;
if (SymbolRef V = getAsPointeeSymbol(ArgExpr, C)) {
// If the argument points to something that's not a symbolic region, it
// can be:
// - unknown (cannot reason about it)
// - undefined (already reported by other checker)
// - constant (null - should not be tracked,
// other constant will generate a compiler warning)
// - goto (should be reported by other checker)
// The call return value symbol should stay alive for as long as the
// allocated value symbol, since our diagnostics depend on the value
// returned by the call. Ex: Data should only be freed if noErr was
// returned during allocation.)
SymbolRef RetStatusSymbol =
State->getSVal(CE, C.getLocationContext()).getAsSymbol();
C.getSymbolManager().addSymbolDependency(V, RetStatusSymbol);
// Track the allocated value in the checker state.
State = State->set<AllocatedData>(V, AllocationState(ArgExpr, idx,
RetStatusSymbol));
assert(State);
C.addTransition(State);
}
}
示例4: checkPreStmt
void DoubleFetchChecker::checkPreStmt(const Expr* E, CheckerContext &Ctx) const {
ProgramStateRef state = Ctx.getState();
SVal ExpVal = state->getSVal(E, Ctx.getLocationContext());
SourceLocation L = E->getExprLoc();
}
示例5: isInvalidSelf
/// \brief Returns true of the value of the expression is the object that 'self'
/// points to and is an object that did not come from the result of calling
/// an initializer.
static bool isInvalidSelf(const Expr *E, CheckerContext &C) {
SVal exprVal = C.getState()->getSVal(E, C.getLocationContext());
if (!hasSelfFlag(exprVal, SelfFlag_Self, C))
return false; // value did not come from 'self'.
if (hasSelfFlag(exprVal, SelfFlag_InitRes, C))
return false; // 'self' is properly initialized.
return true;
}
示例6: addSizeInfo
void ObjCContainersChecker::addSizeInfo(const Expr *Array, const Expr *Size,
CheckerContext &C) const {
ProgramStateRef State = C.getState();
SVal SizeV = State->getSVal(Size, C.getLocationContext());
// Undefined is reported by another checker.
if (SizeV.isUnknownOrUndef())
return;
// Get the ArrayRef symbol.
SVal ArrayRef = State->getSVal(Array, C.getLocationContext());
SymbolRef ArraySym = ArrayRef.getAsSymbol();
if (!ArraySym)
return;
C.addTransition(
State->set<ArraySizeMap>(ArraySym, SizeV.castAs<DefinedSVal>()));
return;
}
示例7: checkPostStmt
void AdjustedReturnValueChecker::checkPostStmt(const CallExpr *CE,
CheckerContext &C) const {
// Get the result type of the call.
QualType expectedResultTy = CE->getType();
// Fetch the signature of the called function.
const ProgramState *state = C.getState();
const LocationContext *LCtx = C.getLocationContext();
SVal V = state->getSVal(CE, LCtx);
if (V.isUnknown())
return;
// Casting to void? Discard the value.
if (expectedResultTy->isVoidType()) {
C.addTransition(state->BindExpr(CE, LCtx, UnknownVal()));
return;
}
const MemRegion *callee = state->getSVal(CE->getCallee(), LCtx).getAsRegion();
if (!callee)
return;
QualType actualResultTy;
if (const FunctionTextRegion *FT = dyn_cast<FunctionTextRegion>(callee)) {
const FunctionDecl *FD = FT->getDecl();
actualResultTy = FD->getResultType();
}
else if (const BlockDataRegion *BD = dyn_cast<BlockDataRegion>(callee)) {
const BlockTextRegion *BR = BD->getCodeRegion();
const BlockPointerType *BT=BR->getLocationType()->getAs<BlockPointerType>();
const FunctionType *FT = BT->getPointeeType()->getAs<FunctionType>();
actualResultTy = FT->getResultType();
}
// Can this happen?
if (actualResultTy.isNull())
return;
// For now, ignore references.
if (actualResultTy->getAs<ReferenceType>())
return;
// Are they the same?
if (expectedResultTy != actualResultTy) {
// FIXME: Do more checking and actual emit an error. At least performing
// the cast avoids some assertion failures elsewhere.
SValBuilder &svalBuilder = C.getSValBuilder();
V = svalBuilder.evalCast(V, expectedResultTy, actualResultTy);
C.addTransition(state->BindExpr(CE, LCtx, V));
}
}
示例8: checkPreObjCMessage
void CallAndMessageChecker::checkPreObjCMessage(ObjCMessage msg,
CheckerContext &C) const {
ProgramStateRef state = C.getState();
const LocationContext *LCtx = C.getLocationContext();
// FIXME: Handle 'super'?
if (const Expr *receiver = msg.getInstanceReceiver()) {
SVal recVal = state->getSVal(receiver, LCtx);
if (recVal.isUndef()) {
if (ExplodedNode *N = C.generateSink()) {
BugType *BT = 0;
if (msg.isPureMessageExpr()) {
if (!BT_msg_undef)
BT_msg_undef.reset(new BuiltinBug("Receiver in message expression "
"is an uninitialized value"));
BT = BT_msg_undef.get();
}
else {
if (!BT_objc_prop_undef)
BT_objc_prop_undef.reset(new BuiltinBug("Property access on an "
"uninitialized object pointer"));
BT = BT_objc_prop_undef.get();
}
BugReport *R =
new BugReport(*BT, BT->getName(), N);
R->addRange(receiver->getSourceRange());
R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
receiver,
R));
C.EmitReport(R);
}
return;
} else {
// Bifurcate the state into nil and non-nil ones.
DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
ProgramStateRef notNilState, nilState;
llvm::tie(notNilState, nilState) = state->assume(receiverVal);
// Handle receiver must be nil.
if (nilState && !notNilState) {
HandleNilReceiver(C, state, msg);
return;
}
}
}
const char *bugDesc = msg.isPropertySetter() ?
"Argument for property setter is an uninitialized value"
: "Argument in message expression is an uninitialized value";
// Check for any arguments that are uninitialized/undefined.
PreVisitProcessArgs(C, CallOrObjCMessage(msg, state, LCtx),
bugDesc, BT_msg_arg);
}
示例9: checkPostStmt
/// Explicit casts are trusted. If there is a disagreement in the nullability
/// annotations in the destination and the source or '0' is casted to nonnull
/// track the value as having contraditory nullability. This will allow users to
/// suppress warnings.
void NullabilityChecker::checkPostStmt(const ExplicitCastExpr *CE,
CheckerContext &C) const {
QualType OriginType = CE->getSubExpr()->getType();
QualType DestType = CE->getType();
if (!OriginType->isAnyPointerType())
return;
if (!DestType->isAnyPointerType())
return;
ProgramStateRef State = C.getState();
if (State->get<PreconditionViolated>())
return;
Nullability DestNullability = getNullabilityAnnotation(DestType);
// No explicit nullability in the destination type, so this cast does not
// change the nullability.
if (DestNullability == Nullability::Unspecified)
return;
auto RegionSVal =
State->getSVal(CE, C.getLocationContext()).getAs<DefinedOrUnknownSVal>();
const MemRegion *Region = getTrackRegion(*RegionSVal);
if (!Region)
return;
// When 0 is converted to nonnull mark it as contradicted.
if (DestNullability == Nullability::Nonnull) {
NullConstraint Nullness = getNullConstraint(*RegionSVal, State);
if (Nullness == NullConstraint::IsNull) {
State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
C.addTransition(State);
return;
}
}
const NullabilityState *TrackedNullability =
State->get<NullabilityMap>(Region);
if (!TrackedNullability) {
if (DestNullability != Nullability::Nullable)
return;
State = State->set<NullabilityMap>(Region,
NullabilityState(DestNullability, CE));
C.addTransition(State);
return;
}
if (TrackedNullability->getValue() != DestNullability &&
TrackedNullability->getValue() != Nullability::Contradicted) {
State = State->set<NullabilityMap>(Region, Nullability::Contradicted);
C.addTransition(State);
}
}
示例10: checkPreStmt
void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS,
CheckerContext &C) const {
ProgramStateRef state = C.getState();
const Expr *RetE = RS->getRetValue();
if (!RetE)
return;
SVal V = state->getSVal(RetE, C.getLocationContext());
const MemRegion *R = V.getAsRegion();
const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(R);
if (!ER)
return;
DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
// Zero index is always in bound, this also passes ElementRegions created for
// pointer casts.
if (Idx.isZeroConstant())
return;
// FIXME: All of this out-of-bounds checking should eventually be refactored
// into a common place.
DefinedOrUnknownSVal NumElements
= C.getStoreManager().getSizeInElements(state, ER->getSuperRegion(),
ER->getValueType());
ProgramStateRef StInBound = state->assumeInBound(Idx, NumElements, true);
ProgramStateRef StOutBound = state->assumeInBound(Idx, NumElements, false);
if (StOutBound && !StInBound) {
ExplodedNode *N = C.generateSink(StOutBound);
if (!N)
return;
// FIXME: This bug correspond to CWE-466. Eventually we should have bug
// types explicitly reference such exploit categories (when applicable).
if (!BT)
BT.reset(new BuiltinBug(
this, "Return of pointer value outside of expected range",
"Returned pointer value points outside the original object "
"(potential buffer overflow)"));
// FIXME: It would be nice to eventually make this diagnostic more clear,
// e.g., by referencing the original declaration or by saying *why* this
// reference is outside the range.
// Generate a report for this bug.
auto report = llvm::make_unique<BugReport>(*BT, BT->getDescription(), N);
report->addRange(RetE->getSourceRange());
C.emitReport(std::move(report));
}
}
示例11: assumeCollectionNonEmpty
static ProgramStateRef
assumeCollectionNonEmpty(CheckerContext &C, ProgramStateRef State,
const ObjCForCollectionStmt *FCS,
bool Assumption) {
if (!State)
return nullptr;
SymbolRef CollectionS =
State->getSVal(FCS->getCollection(), C.getLocationContext()).getAsSymbol();
return assumeCollectionNonEmpty(C, State, CollectionS, Assumption);
}
示例12: checkPreCall
void CallDumper::checkPreCall(const CallEvent &Call, CheckerContext &C) const {
unsigned Indentation = 0;
for (const LocationContext *LC = C.getLocationContext()->getParent();
LC != nullptr; LC = LC->getParent())
++Indentation;
// It is mildly evil to print directly to llvm::outs() rather than emitting
// warnings, but this ensures things do not get filtered out by the rest of
// the static analyzer machinery.
llvm::outs().indent(Indentation);
Call.dump(llvm::outs());
}
示例13: checkPreStmt
void CastSizeChecker::checkPreStmt(const CastExpr *CE,CheckerContext &C) const {
const Expr *E = CE->getSubExpr();
ASTContext &Ctx = C.getASTContext();
QualType ToTy = Ctx.getCanonicalType(CE->getType());
const PointerType *ToPTy = dyn_cast<PointerType>(ToTy.getTypePtr());
if (!ToPTy)
return;
QualType ToPointeeTy = ToPTy->getPointeeType();
// Only perform the check if 'ToPointeeTy' is a complete type.
if (ToPointeeTy->isIncompleteType())
return;
ProgramStateRef state = C.getState();
const MemRegion *R = state->getSVal(E, C.getLocationContext()).getAsRegion();
if (!R)
return;
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R);
if (!SR)
return;
SValBuilder &svalBuilder = C.getSValBuilder();
SVal extent = SR->getExtent(svalBuilder);
const llvm::APSInt *extentInt = svalBuilder.getKnownValue(state, extent);
if (!extentInt)
return;
CharUnits regionSize = CharUnits::fromQuantity(extentInt->getSExtValue());
CharUnits typeSize = C.getASTContext().getTypeSizeInChars(ToPointeeTy);
// Ignore void, and a few other un-sizeable types.
if (typeSize.isZero())
return;
if (regionSize % typeSize == 0)
return;
if (evenFlexibleArraySize(Ctx, regionSize, typeSize, ToPointeeTy))
return;
if (ExplodedNode *errorNode = C.generateErrorNode()) {
if (!BT)
BT.reset(new BuiltinBug(this, "Cast region with wrong size.",
"Cast a region whose size is not a multiple"
" of the destination type size."));
auto R = llvm::make_unique<BugReport>(*BT, BT->getDescription(), errorNode);
R->addRange(CE->getSourceRange());
C.emitReport(std::move(R));
}
}
示例14: checkPreStmt
void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
CheckerContext &C) const {
const Expr *Ex = S->getSynchExpr();
ProgramStateRef state = C.getState();
SVal V = state->getSVal(Ex, C.getLocationContext());
// Uninitialized value used for the mutex?
if (V.getAs<UndefinedVal>()) {
if (ExplodedNode *N = C.generateSink()) {
if (!BT_undef)
BT_undef.reset(new BuiltinBug(this, "Uninitialized value used as mutex "
"for @synchronized"));
BugReport *report =
new BugReport(*BT_undef, BT_undef->getDescription(), N);
bugreporter::trackNullOrUndefValue(N, Ex, *report);
C.emitReport(report);
}
return;
}
if (V.isUnknown())
return;
// Check for null mutexes.
ProgramStateRef notNullState, nullState;
llvm::tie(notNullState, nullState) = state->assume(V.castAs<DefinedSVal>());
if (nullState) {
if (!notNullState) {
// Generate an error node. This isn't a sink since
// a null mutex just means no synchronization occurs.
if (ExplodedNode *N = C.addTransition(nullState)) {
if (!BT_null)
BT_null.reset(new BuiltinBug(
this, "Nil value used as mutex for @synchronized() "
"(no synchronization will occur)"));
BugReport *report =
new BugReport(*BT_null, BT_null->getDescription(), N);
bugreporter::trackNullOrUndefValue(N, Ex, *report);
C.emitReport(report);
return;
}
}
// Don't add a transition for 'nullState'. If the value is
// under-constrained to be null or non-null, assume it is non-null
// afterwards.
}
if (notNullState)
C.addTransition(notNullState);
}
示例15: checkBeginFunction
/// If this is the beginning of -dealloc, mark the values initially stored in
/// instance variables that must be released by the end of -dealloc
/// as unreleased in the state.
void ObjCDeallocChecker::checkBeginFunction(
CheckerContext &C) const {
initIdentifierInfoAndSelectors(C.getASTContext());
// Only do this if the current method is -dealloc.
SVal SelfVal;
if (!isInInstanceDealloc(C, SelfVal))
return;
SymbolRef SelfSymbol = SelfVal.getAsSymbol();
const LocationContext *LCtx = C.getLocationContext();
ProgramStateRef InitialState = C.getState();
ProgramStateRef State = InitialState;
SymbolSet::Factory &F = State->getStateManager().get_context<SymbolSet>();
// Symbols that must be released by the end of the -dealloc;
SymbolSet RequiredReleases = F.getEmptySet();
// If we're an inlined -dealloc, we should add our symbols to the existing
// set from our subclass.
if (const SymbolSet *CurrSet = State->get<UnreleasedIvarMap>(SelfSymbol))
RequiredReleases = *CurrSet;
for (auto *PropImpl : getContainingObjCImpl(LCtx)->property_impls()) {
ReleaseRequirement Requirement = getDeallocReleaseRequirement(PropImpl);
if (Requirement != ReleaseRequirement::MustRelease)
continue;
SVal LVal = State->getLValue(PropImpl->getPropertyIvarDecl(), SelfVal);
Optional<Loc> LValLoc = LVal.getAs<Loc>();
if (!LValLoc)
continue;
SVal InitialVal = State->getSVal(LValLoc.getValue());
SymbolRef Symbol = InitialVal.getAsSymbol();
if (!Symbol || !isa<SymbolRegionValue>(Symbol))
continue;
// Mark the value as requiring a release.
RequiredReleases = F.add(RequiredReleases, Symbol);
}
if (!RequiredReleases.isEmpty()) {
State = State->set<UnreleasedIvarMap>(SelfSymbol, RequiredReleases);
}
if (State != InitialState) {
C.addTransition(State);
}
}