21using namespace retaincountchecker;
27namespace retaincountchecker {
30 return State->get<RefBindings>(Sym);
39 assert(Sym !=
nullptr);
40 return State->set<RefBindings>(Sym, Val);
44 return State->remove<RefBindings>(Sym);
49 Out <<
"Tracked " << T <<
" | ";
52 default: llvm_unreachable(
"Invalid RefVal kind");
56 if (cnt) Out <<
" (+ " << cnt <<
")";
63 if (cnt) Out <<
" (+ " << cnt <<
")";
68 Out <<
"ReturnedOwned";
70 if (cnt) Out <<
" (+ " << cnt <<
")";
75 Out <<
"ReturnedNotOwned";
77 if (cnt) Out <<
" (+ " << cnt <<
")";
86 Out <<
"-dealloc (not-owned)";
94 Out <<
"Leaked (Bad naming)";
98 Out <<
"Use-After-Release [ERROR]";
102 Out <<
"Release of Not-Owned [ERROR]";
106 Out <<
"Over-autoreleased";
110 Out <<
"Non-owned object returned instead of owned";
118 Out <<
" [direct ivar access]";
121 Out <<
" [released after direct ivar access]";
125 Out <<
" [autorelease -" << ACnt <<
']';
136 bool VisitSymbol(
SymbolRef sym)
override {
156 auto *R = cast<BlockDataRegion>(
C.getSVal(BE).getAsRegion());
159 E = R->referenced_vars_end();
171 for ( ; I != E; ++I) {
176 Regions.push_back(VR);
179 state = state->scanReachableSymbols<StopTrackingCallback>(Regions).getState();
180 C.addTransition(state);
212 SymbolRef Sym =
C.getSVal(CE).getAsLocSymbol();
227 C.addTransition(state);
231 const Expr *Ex)
const {
257 C.addTransition(state);
283 C.addTransition(State);
288 std::optional<Loc> IVarLoc =
C.getSVal(IRE).getAs<
Loc>();
293 SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol();
336 C.addTransition(State);
340 if (
const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
344 return MC->getMethodFamily() ==
OMF_init && MC->isReceiverSelfOrSuper() &&
345 !Call.getLocationContext()
346 ->getAnalysisDeclContext()
348 .isConsumedExpr(Call.getOriginExpr());
356 const Expr *CE = Call.getOriginExpr();
359 :
AnyCall(cast<CXXDestructorDecl>(Call.getDecl()));
360 return Summaries.
getSummary(
C, Call.hasNonZeroCallbackArg(),
370 if (
const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
371 if (MC->isInstanceMessage()) {
372 SVal ReceiverV = MC->getReceiverSVal();
375 ReceiverType = T->getType();
402 if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() ||
403 PT->isObjCClassType()) {
438 const RefVal *TrackedValue) {
455 for (
unsigned idx = 0, e = CallOrMsg.
getNumArgs(); idx != e; ++idx) {
462 ShouldRemoveBinding =
true;
464 if (ShouldRemoveBinding)
470 if (
const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
471 if (
SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
486 C.addTransition(state);
490 const auto *TR = dyn_cast<TypedValueRegion>(
491 cast<SubRegion>(MR)->getSuperRegion());
510 const auto *VR = dyn_cast<VarRegion>(R);
515 const VarDecl *VD = VR->getDecl();
516 if (!VD->
hasAttr<CleanupAttr>())
531 bool SplitNecessary =
false;
535 SplitNecessary =
true;
540 if (SplitNecessary) {
547 AssumeNonZeroReturn = AssumeNonZeroReturn->assume(*DL,
true);
548 AssumeZeroReturn = AssumeZeroReturn->assume(*DL,
false);
552 for (
unsigned idx = 0, e = CE.
getNumArgs(); idx != e; ++idx) {
556 auto *ArgRegion = dyn_cast_or_null<TypedValueRegion>(ArgVal.
getAsRegion());
560 QualType PointeeTy = ArgRegion->getValueType();
561 SVal PointeeVal = State->getSVal(ArgRegion);
580 AssumeNonZeroReturn = makeNotOwnedParameter(AssumeNonZeroReturn);
581 AssumeZeroReturn = makeNotOwnedParameter(AssumeZeroReturn);
584 AssumeNonZeroReturn = makeOwnedParameter(AssumeNonZeroReturn);
585 AssumeZeroReturn = makeOwnedParameter(AssumeZeroReturn);
588 AssumeNonZeroReturn = makeOwnedParameter(AssumeNonZeroReturn);
591 AssumeZeroReturn = makeOwnedParameter(AssumeZeroReturn);
598 if (SplitNecessary) {
599 return {AssumeNonZeroReturn, AssumeZeroReturn};
601 assert(AssumeZeroReturn == AssumeNonZeroReturn);
602 return {AssumeZeroReturn};
618 bool DeallocSent =
false;
620 for (
unsigned idx = 0, e = CallOrMsg.
getNumArgs(); idx != e; ++idx) {
643 bool ReceiverIsTracked =
false;
645 if (
const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
646 if (
SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
648 ReceiverIsTracked =
true;
652 ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
659 }
else if (
const auto *MCall = dyn_cast<CXXMemberCall>(&CallOrMsg)) {
660 if (
SymbolRef Sym = MCall->getCXXThisVal().getAsLocSymbol()) {
665 ErrorRange = MCall->getOriginExpr()->getSourceRange();
683 if (ReceiverIsTracked)
717 bool IgnoreRetainMsg = (
bool)
C.getASTContext().getLangOpts().ObjCAutoRefCount;
737 hasErr =
V.getKind();
746 llvm_unreachable(
"Applies to pointer-to-pointer parameters, which should "
747 "not have ref state.");
750 switch (
V.getKind()) {
752 llvm_unreachable(
"Invalid RefVal state for an explicit dealloc.");
760 hasErr =
V.getKind();
786 switch (
V.getKind()) {
788 llvm_unreachable(
"Invalid RefVal state for a retain.");
799 switch (
V.getKind()) {
802 llvm_unreachable(
"Invalid RefVal state for a release.");
805 assert(
V.getCount() > 0);
806 if (
V.getCount() == 1) {
808 V.getIvarAccessHistory() ==
821 if (
V.getCount() > 0) {
825 }
else if (
V.getIvarAccessHistory() ==
834 hasErr =
V.getKind();
856 llvm_unreachable(
"Unhandled error.");
879 auto report = std::make_unique<RefCountReport>(
881 C.getASTContext().getLangOpts(), N, Sym);
882 report->addRange(ErrorRange);
883 C.emitReport(std::move(report));
893 const auto *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
897 const auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
902 QualType ResultTy = Call.getResultType();
906 bool hasTrustedImplementationAnnotation =
false;
911 std::optional<BehaviorSummary> BSmr =
912 SmrMgr.
canEval(CE, FD, hasTrustedImplementationAnnotation);
919 if (BSmr == BehaviorSummary::Identity ||
920 BSmr == BehaviorSummary::IdentityOrZero ||
921 BSmr == BehaviorSummary::IdentityThis) {
923 const Expr *BindReturnTo =
924 (BSmr == BehaviorSummary::IdentityThis)
925 ? cast<CXXMemberCallExpr>(CE)->getImplicitObjectArgument()
927 SVal RetVal = state->getSVal(BindReturnTo, LCtx);
934 (hasTrustedImplementationAnnotation && !ResultTy.
isNull())) {
941 state = state->BindExpr(CE, LCtx, RetVal,
false);
943 if (BSmr == BehaviorSummary::IdentityOrZero) {
948 NullOutputState = NullOutputState->BindExpr(
949 CE, LCtx,
C.getSValBuilder().makeNullWithType(ResultTy),
956 state = state->assume(*L,
true);
961 C.addTransition(state);
980 const Expr *RetE = S->getRetValue();
987 SymbolRef Sym = state->getSValAsScalarOrLoc(RetE,
C.getLocationContext())
988 .getAsLocSymbol(
true);
1000 switch (
X.getKind()) {
1002 unsigned cnt =
X.getCount();
1004 X.setCount(cnt - 1);
1010 unsigned cnt =
X.getCount();
1012 X.setCount(cnt - 1);
1026 Pred =
C.addTransition(state);
1058 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
1059 if (!isa<CXXMethodDecl>(FD)) {
1084 if (
X.isReturnedOwned() &&
X.getCount() == 0) {
1096 ExplodedNode *N =
C.addTransition(state, Pred, &ReturnOwnLeakTag);
1098 const LangOptions &LOpts =
C.getASTContext().getLangOpts();
1100 std::make_unique<RefLeakReport>(*
LeakAtReturn, LOpts, N, Sym,
C);
1101 C.emitReport(std::move(R));
1106 }
else if (
X.isReturnedNotOwned()) {
1108 if (
X.getIvarAccessHistory() ==
1120 ReturnNotOwnedTag(
this,
"ReturnNotOwnedForOwned");
1122 ExplodedNode *N =
C.addTransition(state, Pred, &ReturnNotOwnedTag);
1124 auto R = std::make_unique<RefCountReport>(
1126 C.emitReport(std::move(R));
1147 state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
1148 C.addTransition(state);
1154 bool Assumption)
const {
1161 RefBindingsTy B = state->get<RefBindings>();
1166 bool changed =
false;
1167 RefBindingsTy::Factory &RefBFactory = state->get_context<RefBindings>();
1175 B = RefBFactory.remove(B, I.first);
1180 state = state->set<RefBindings>(B);
1195 for (
const MemRegion *I : ExplicitRegions)
1197 AllowedSymbols.insert(SR->getSymbol());
1200 if (AllowedSymbols.count(sym))
1216 unsigned ACnt =
V.getAutoreleaseCount();
1222 unsigned Cnt =
V.getCount();
1233 V =
V.releaseViaIvar();
1246 V.setCount(
V.getCount() - ACnt);
1247 V.setAutoreleaseCount(0);
1269 llvm::raw_svector_ostream os(sbuf);
1270 os <<
"Object was autoreleased ";
1271 if (
V.getAutoreleaseCount() > 1)
1272 os <<
V.getAutoreleaseCount() <<
" times but the object ";
1275 os <<
"has a +" <<
V.getCount() <<
" retain count";
1278 auto R = std::make_unique<RefCountReport>(*
OverAutorelease, LOpts, N, Sym,
1300 else if (
V.isOwned())
1302 else if (
V.isNotOwned() ||
V.isReturnedOwned())
1303 hasLeak = (
V.getCount() > 0);
1310 Leaked.push_back(sid);
1326 Ctx.
emitReport(std::make_unique<RefLeakReport>(BT, LOpts, N, L, Ctx));
1349 for (
unsigned idx = 0, e =
C->param_size(); idx != e; ++idx) {
1351 SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol();
1354 const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
1379 RefBindingsTy B = state->get<RefBindings>();
1383 if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) {
1384 assert(!LCtx->inTopFrame());
1399 if (LCtx->getParent())
1402 B = state->get<RefBindings>();
1419 for (
const auto &I: state->get<RefBindings>()) {
1421 if (SymReaper.
isDead(Sym)) {
1434 if (Leaked.empty()) {
1435 C.addTransition(state);
1447 RefBindingsTy::Factory &F = state->get_context<RefBindings>();
1448 RefBindingsTy B = state->get<RefBindings>();
1453 state = state->set<RefBindings>(B);
1454 C.addTransition(state, Pred);
1458 const char *NL,
const char *Sep)
const {
1460 RefBindingsTy B = State->get<RefBindings>();
1468 Out << I.first <<
" : ";
1469 I.second.print(Out);
1484 std::make_unique<CheckerProgramPointTag>(Chk,
"DeallocSent");
1486 std::make_unique<CheckerProgramPointTag>(Chk,
"DynamicCastFail");
1489bool ento::shouldRegisterRetainCountBase(
const CheckerManager &mgr) {
1498#define INIT_BUGTYPE(KIND) \
1499 Chk->KIND = std::make_unique<RefCountBug>(Mgr.getCurrentCheckerName(), \
1513bool ento::shouldRegisterRetainCountChecker(
const CheckerManager &mgr) {
1517void ento::registerOSObjectRetainCountChecker(
CheckerManager &Mgr) {
1530#define LAZY_INIT_BUGTYPE(KIND) \
1532 Chk->KIND = std::make_unique<RefCountBug>(Mgr.getCurrentCheckerName(), \
1542#undef LAZY_INIT_BUGTYPE
1545bool ento::shouldRegisterOSObjectRetainCountChecker(
const CheckerManager &mgr) {
static CanQualType GetReturnType(QualType RetTy)
Returns the "extra-canonicalized" return type, which discards qualifiers on the return type.
static CompilationDatabasePluginRegistry::Add< FixedCompilationDatabasePlugin > X("fixed-compilation-database", "Reads plain-text flags file")
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
#define LAZY_INIT_BUGTYPE(KIND)
static const RetainSummary * getSummary(RetainSummaryManager &Summaries, const CallEvent &Call, QualType ReceiverType)
static std::optional< RefVal > refValFromRetEffect(RetEffect RE, QualType ResultTy)
static ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym, RefVal Val)
static bool isReceiverUnconsumedSelf(const CallEvent &Call)
static SmallVector< ProgramStateRef, 2 > updateOutParameters(ProgramStateRef State, const RetainSummary &Summ, const CallEvent &CE)
static ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym)
#define INIT_BUGTYPE(KIND)
static bool isPointerToObject(QualType QT)
static bool isSmartPtrField(const MemRegion *MR)
static bool shouldEscapeOSArgumentOnCall(const CallEvent &CE, unsigned ArgIdx, const RefVal *TrackedValue)
Whether the tracked value should be escaped on a given call.
static bool shouldEscapeRegion(const MemRegion *R)
A value escapes in these possible cases:
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
const LangOptions & getLangOpts() const
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName, bool SearchInParents=false) const
Interprets an option's string value as a boolean.
An instance of this class corresponds to a call.
static std::optional< AnyCall > forDecl(const Decl *D)
If D is a callable (Objective-C method or a function), return a constructed AnyCall object.
static std::optional< AnyCall > forExpr(const Expr *E)
If E is a generic call (to ObjC method /function/block/etc), return a constructed AnyCall object.
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
const BlockDecl * getBlockDecl() const
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Decl - This represents one declaration (or definition), e.g.
This represents one expression.
Represents a function declaration or definition.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const Decl * getDecl() const
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
ObjCBoxedExpr - used for generalized expression boxing.
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
ObjCBridgeCastKind getBridgeKind() const
Determine which kind of bridge is being performed via this cast.
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Represents an ObjC class declaration.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
ObjCMethodDecl - Represents an instance or class method declaration.
Represents a pointer to an Objective C object.
Represents a parameter to a function.
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isScalarType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isObjCObjectPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isObjCRetainableType() const
Represents a variable declaration or definition.
An ArgEffect summarizes the retain count behavior on an argument or receiver to a function or method.
ArgEffect withKind(ArgEffectKind NewK)
ObjKind getObjKind() const
ArgEffectKind getKind() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const VarRegion * getCapturedRegion() const
Represents an abstract call to a function or method along a particular path.
virtual SourceRange getArgSourceRange(unsigned Index) const
Returns the source range for errors associated with this argument.
virtual const Expr * getOriginExpr() const
Returns the expression whose value will be the result of this call.
QualType getResultType() const
Returns the result type, adjusted for references.
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
virtual unsigned getNumArgs() const =0
Returns the number of arguments (explicit and implicit).
SVal getReturnValue() const
Returns the return value of the call.
virtual ArrayRef< ParmVarDecl * > parameters() const =0
Return call's formal parameters.
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Generate a sink node.
ASTContext & getASTContext()
const ProgramStateRef & getState() const
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
bool inTopFrame() const
Return true if the current LocationContext has no caller context.
const LocationContext * getLocationContext() const
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
const AnalyzerOptions & getAnalyzerOptions() const
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
CheckerNameRef getCurrentCheckerName() const
Tag that can use a checker name as a message provider (see SimpleProgramPointTag).
bool isConstrainedTrue() const
Return true if the constraint is perfectly constrained to 'true'.
ConditionTruthVal isNull(ProgramStateRef State, SymbolRef Sym)
Convenience method to query the state to see if a symbol is null or not null, or if neither assumptio...
const ProgramStateRef & getState() const
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
const LocationContext * getLocationContext() const
const Decl & getCodeDecl() const
const VarRegion * getVarRegion(const VarDecl *VD, const LocationContext *LC)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and LocationC...
MemRegion - The root abstract class for all memory regions.
bool hasStackStorage() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
const RegionTy * getAs() const
RetEffect summarizes a call's retain/release behavior with respect to its return value.
ObjKind getObjKind() const
@ OwnedWhenTrackedReceiver
Indicates that the return value is an owned object when the receiver is also a tracked object.
@ NoRet
Indicates that no retain count information is tracked for the return value.
static RetEffect MakeNoRet()
bool isTrustedReferenceCountImplementation(const Decl *FD)
std::optional< BehaviorSummary > canEval(const CallExpr *CE, const FunctionDecl *FD, bool &hasTrustedImplementationAnnotation)
static bool isKnownSmartPointer(QualType QT)
const RetainSummary * getSummary(AnyCall C, bool HasNonZeroCallbackArg=false, bool IsReceiverUnconsumedSelf=false, QualType ReceiverType={})
RetEffect getObjAllocRetEffect() const
Summary for a function with respect to ownership changes.
ArgEffect getThisEffect() const
ArgEffect getReceiverEffect() const
getReceiverEffect - Returns the effect on the receiver of the call.
RetEffect getRetEffect() const
getRetEffect - Returns the effect on the return value of the call.
ArgEffects getArgEffects() const
ArgEffect getArg(unsigned idx) const
getArg - Return the argument effect on the argument specified by idx (starting from 0).
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef.
const MemRegion * getAsRegion() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getSuperRegion() const
virtual const MemRegion * getOriginRegion() const
Find the region from which this symbol originates.
virtual QualType getType() const =0
A class responsible for cleaning up unused symbols.
bool isDead(SymbolRef sym)
Returns whether or not a symbol has been confirmed dead.
SymbolicRegion - A special, "non-concrete" region.
const VarDecl * getDecl() const override=0
unsigned getCount() const
@ ReleasedAfterDirectAccess
IvarAccessHistory getIvarAccessHistory() const
Returns what the analyzer knows about direct accesses to a particular instance variable.
void print(raw_ostream &Out) const
RefVal withIvarAccess() const
static RefVal makeOwned(ObjKind o, QualType t)
Create a state for an object whose lifetime is the responsibility of the current function,...
ObjKind getObjKind() const
static RefVal makeNotOwned(ObjKind o, QualType t)
Create a state for an object whose lifetime is not the responsibility of the current function.
std::unique_ptr< RefCountBug > LeakAtReturn
void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const
void checkSummary(const RetainSummary &Summ, const CallEvent &Call, CheckerContext &C) const
ProgramStateRef handleSymbolDeath(ProgramStateRef state, SymbolRef sid, RefVal V, SmallVectorImpl< SymbolRef > &Leaked) const
static std::unique_ptr< CheckerProgramPointTag > CastFailTag
bool TrackObjCAndCFObjects
Track Objective-C and CoreFoundation objects.
ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, bool Assumption) const
static std::unique_ptr< CheckerProgramPointTag > DeallocSentTag
static const CheckerProgramPointTag & getCastFailTag()
void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange, RefVal::Kind ErrorKind, SymbolRef Sym, CheckerContext &C) const
const RefCountBug & errorKindToBugKind(RefVal::Kind ErrorKind, SymbolRef Sym) const
std::unique_ptr< RefCountBug > ReleaseNotOwned
std::unique_ptr< RefCountBug > DeallocNotOwned
void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const
ExplodedNode * checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C, ExplodedNode *Pred, RetEffect RE, RefVal X, SymbolRef Sym, ProgramStateRef state) const
ProgramStateRef handleAutoreleaseCounts(ProgramStateRef state, ExplodedNode *Pred, const ProgramPointTag *Tag, CheckerContext &Ctx, SymbolRef Sym, RefVal V, const ReturnStmt *S=nullptr) const
std::unique_ptr< RefCountBug > OverAutorelease
ExplodedNode * processLeaks(ProgramStateRef state, SmallVectorImpl< SymbolRef > &Leaked, CheckerContext &Ctx, ExplodedNode *Pred=nullptr) const
ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym, RefVal V, ArgEffect E, RefVal::Kind &hasErr, CheckerContext &C) const
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const
static const CheckerProgramPointTag & getDeallocSentTag()
std::unique_ptr< RetainSummaryManager > Summaries
void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const override
See CheckerManager::runCheckersForPrintState.
bool evalCall(const CallEvent &Call, CheckerContext &C) const
void checkBeginFunction(CheckerContext &C) const
bool TrackOSObjects
Track sublcasses of OSObject.
void checkPostCall(const CallEvent &Call, CheckerContext &C) const
std::unique_ptr< RefCountBug > FreeNotOwned
std::unique_ptr< RefCountBug > LeakWithinFunction
ProgramStateRef checkRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const LocationContext *LCtx, const CallEvent *Call) const
void processObjCLiterals(CheckerContext &C, const Expr *Ex) const
void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const
void processSummaryOfInlined(const RetainSummary &Summ, const CallEvent &Call, CheckerContext &C) const
std::unique_ptr< RefCountBug > ReturnNotOwnedForOwned
RetainSummaryManager & getSummaryManager(ASTContext &Ctx) const
bool TrackNSCFStartParam
Track initial parameters (for the entry point) for NS/CF objects.
std::unique_ptr< RefCountBug > UseAfterRelease
bool isCFObjectRef(QualType T)
const RefVal * getRefBinding(ProgramStateRef State, SymbolRef Sym)
bool isSynthesizedAccessor(const StackFrameContext *SFC)
Returns true if this stack frame is for an Objective-C method that is a property getter or setter who...
llvm::ImmutableMap< unsigned, ArgEffect > ArgEffects
ArgEffects summarizes the effects of a function/method call on all of its arguments.
ObjKind
Determines the object kind of a tracked object.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ Generalized
Indicates that the tracked object is a generalized object.
@ CF
Indicates that the tracked object is a CF object.
@ ObjC
Indicates that the tracked object is an Objective-C object.
@ IncRef
The argument has its reference count increased by 1.
@ UnretainedOutParameter
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +0 v...
@ DoNothing
There is no effect.
@ RetainedOutParameter
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
@ RetainedOutParameterOnZero
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
@ MayEscape
The argument is treated as potentially escaping, meaning that even when its reference count hits 0 it...
@ StopTracking
All typestate tracking of the object ceases.
@ Dealloc
The argument is treated as if the referenced object was deallocated.
@ Autorelease
The argument is treated as if an -autorelease message had been sent to the referenced object.
@ RetainedOutParameterOnNonZero
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
@ DecRef
The argument has its reference count decreased by 1.
@ StopTrackingHard
All typestate tracking of the object ceases.
@ DecRefAndStopTrackingHard
Performs the combined functionality of DecRef and StopTrackingHard.
@ DecRefBridgedTransferred
The argument has its reference count decreased by 1 to model a transferred bridge cast under ARC.
@ C
Languages that the frontend can parse and compile.
@ OBC_Bridge
Bridging via __bridge, which does nothing but reinterpret the bits.
@ OBC_BridgeTransfer
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC.
@ OBC_BridgeRetained
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.