A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://clang.llvm.org/doxygen/CheckObjCDealloc_8cpp_source.html below:

clang: lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp Source File

47#include "llvm/Support/raw_ostream.h" 50using namespace clang

;

93class

ObjCDeallocChecker

94

:

public Checker

<check::ASTDecl<ObjCImplementationDecl>,

95

check::PreObjCMessage, check::PostObjCMessage,

97

check::BeginFunction, check::EndFunction,

100

check::PreStmt<ReturnStmt>> {

111 const BugType

MissingReleaseBugType{

this

,

"Missing ivar release (leak)"

,

113 const BugType

ExtraReleaseBugType{

this

,

"Extra ivar release"

,

115 const BugType

MistakenDeallocBugType{

this

,

"Mistaken dealloc"

,

127 bool

Assumption)

const

;

142 bool

diagnoseMistakenDealloc(

SymbolRef

DeallocedValue,

153

findPropertyOnDeallocatingInstance(

SymbolRef

IvarSym,

161 SVal

&SelfValOut)

const

;

163 SVal

&InstanceValOut)

const

;

177 void

initIdentifierInfoAndSelectors(

ASTContext

&Ctx)

const

;

198

assert(Mgr.

getLangOpts

().getGC() != LangOptions::GCOnly);

205 if

(classHasSeparateTeardown(ID))

211 bool

HasOthers =

false

;

212 for

(

const auto

*I :

D

->property_impls()) {

214 if

(!PropImplRequiringRelease)

215

PropImplRequiringRelease = I;

223 if

(!PropImplRequiringRelease)

229 for

(

const auto

*I :

D

->instance_methods()) {

230 if

(I->getSelector() == DeallocSel) {

237 const char

* Name =

"Missing -dealloc"

;

240

llvm::raw_string_ostream OS(Buf);

241

OS <<

"'"

<< *

D

<<

"' lacks a 'dealloc' instance method but " 246

OS <<

" and others"

;

259void

ObjCDeallocChecker::checkBeginFunction(

261

initIdentifierInfoAndSelectors(

C

.getASTContext());

265 if

(!isInInstanceDealloc(

C

, SelfVal))

275

SymbolSet::Factory &F = State->getStateManager().get_context<

SymbolSet

>();

278 SymbolSet

RequiredReleases = F.getEmptySet();

282 if

(

const SymbolSet

*CurrSet = State->get<UnreleasedIvarMap>(SelfSymbol))

283

RequiredReleases = *CurrSet;

285 for

(

auto

*PropImpl : getContainingObjCImpl(LCtx)->property_impls()) {

290 SVal

LVal = State->getLValue(PropImpl->getPropertyIvarDecl(), SelfVal);

291

std::optional<Loc> LValLoc = LVal.

getAs

<

Loc

>();

295 SVal

InitialVal = State->getSVal(*LValLoc);

297 if

(!Symbol || !isa<SymbolRegionValue>(Symbol))

301

RequiredReleases = F.add(RequiredReleases, Symbol);

304 if

(!RequiredReleases.isEmpty()) {

305

State = State->set<UnreleasedIvarMap>(SelfSymbol, RequiredReleases);

308 if

(State != InitialState) {

309 C

.addTransition(State);

316

ObjCDeallocChecker::getIvarRegionForIvarSymbol(

SymbolRef

IvarSym)

const

{

323

ObjCDeallocChecker::getInstanceSymbolFromIvarSymbol(

SymbolRef

IvarSym)

const

{

325 const ObjCIvarRegion

*IvarRegion = getIvarRegionForIvarSymbol(IvarSym);

330

assert(SR &&

"Symbolic base should not be nullptr"

);

336void

ObjCDeallocChecker::checkPreObjCMessage(

339 SVal

DeallocedInstance;

340 if

(!instanceDeallocIsOnStack(

C

, DeallocedInstance))

355 if

(diagnoseExtraRelease(ReleasedValue,M,

C

))

360

ReleasedValue = getValueReleasedByNillingOut(M,

C

);

366

transitionToReleaseValue(

C

, ReleasedValue);

371void

ObjCDeallocChecker::checkPreCall(

const CallEvent

&

Call

,

374 if

(II != Block_releaseII)

377 if

(

Call

.getNumArgs() != 1)

384

transitionToReleaseValue(

C

, ReleasedValue);

388void

ObjCDeallocChecker::checkPostObjCMessage(

393 if

(isSuperDeallocMessage(M))

394

diagnoseMissingReleases(

C

);

399void

ObjCDeallocChecker::checkEndFunction(

401

diagnoseMissingReleases(

C

);

405void

ObjCDeallocChecker::checkPreStmt(

407

diagnoseMissingReleases(

C

);

413 bool

Assumption)

const

{

414 if

(State->get<UnreleasedIvarMap>().isEmpty())

417 auto

*CondBSE = dyn_cast_or_null<BinarySymExpr>(Cond.

getAsSymbol

());

431 if

(

auto

*SIE = dyn_cast<SymIntExpr>(CondBSE)) {

432 const

llvm::APInt &RHS = SIE->getRHS();

435

NullSymbol = SIE->getLHS();

436

}

else if

(

auto

*SIE = dyn_cast<IntSymExpr>(CondBSE)) {

437 const

llvm::APInt &LHS = SIE->getLHS();

440

NullSymbol = SIE->getRHS();

445 SymbolRef

InstanceSymbol = getInstanceSymbolFromIvarSymbol(NullSymbol);

449

State = removeValueRequiringRelease(State, InstanceSymbol, NullSymbol);

459 if

(State->get<UnreleasedIvarMap>().isEmpty())

466 auto

*OMC = dyn_cast_or_null<ObjCMethodCall>(

Call

);

467 if

(OMC && isSuperDeallocMessage(*OMC))

470 for

(

const auto

&Sym : Escaped) {

479

State = State->remove<UnreleasedIvarMap>(Sym);

483 SymbolRef

InstanceSymbol = getInstanceSymbolFromIvarSymbol(Sym);

487

State = removeValueRequiringRelease(State, InstanceSymbol, Sym);

495void

ObjCDeallocChecker::diagnoseMissingReleases(

CheckerContext

&

C

)

const

{

499 if

(!isInInstanceDealloc(

C

, SelfVal))

511 const SymbolSet

*OldUnreleased = State->get<UnreleasedIvarMap>(SelfSym);

515 SymbolSet

NewUnreleased = *OldUnreleased;

516

SymbolSet::Factory &F = State->getStateManager().get_context<

SymbolSet

>();

520 for

(

auto

*IvarSymbol : *OldUnreleased) {

522

cast<SymbolRegionValue>(IvarSymbol)->getRegion();

533

cast<ObjCMethodDecl>(LCtx->

getDecl

())->getClassInterface())

538

NewUnreleased = F.remove(NewUnreleased, IvarSymbol);

540 if

(State->getStateManager()

541

.getConstraintManager()

542

.isNull(State, IvarSymbol)

543

.isConstrainedTrue()) {

549

ErrNode =

C

.generateNonFatalErrorNode();

556

llvm::raw_string_ostream OS(Buf);

563 if

(classHasSeparateTeardown(

Interface

))

576

OS <<

"The '"

<< *IvarDecl <<

"' ivar in '"

<< *ImplDecl

584

OS <<

" by a synthesized property but not released" 585 " before '[super dealloc]'"

;

587 auto

BR = std::make_unique<PathSensitiveBugReport>(MissingReleaseBugType,

589 C

.emitReport(std::move(BR));

592 if

(NewUnreleased.isEmpty()) {

593

State = State->remove<UnreleasedIvarMap>(SelfSym);

595

State = State->set<UnreleasedIvarMap>(SelfSym, NewUnreleased);

599 C

.addTransition(State, ErrNode);

600

}

else if

(State != InitialState) {

601 C

.addTransition(State);

607

assert(!LCtx->

inTopFrame

() || State->get<UnreleasedIvarMap>().isEmpty());

614

ObjCDeallocChecker::findPropertyOnDeallocatingInstance(

616 SVal

DeallocedInstance;

617 if

(!isInInstanceDealloc(

C

, DeallocedInstance))

621 auto

*IvarRegion = getIvarRegionForIvarSymbol(IvarSym);

634 const ObjCImplDecl

*Container = getContainingObjCImpl(LCtx);

636

Container->FindPropertyImplIvarDecl(IvarDecl->

getIdentifier

());

643bool

ObjCDeallocChecker::diagnoseExtraRelease(

SymbolRef

ReleasedValue,

652

findPropertyOnDeallocatingInstance(ReleasedValue,

C

);

659 if

(getDeallocReleaseRequirement(PropImpl) !=

683

llvm::raw_string_ostream OS(Buf);

688

isReleasedByCIFilterDealloc(PropImpl)

691 const ObjCImplDecl

*Container = getContainingObjCImpl(

C

.getLocationContext());

693

<<

"' ivar in '"

<< *Container;

696 if

(isReleasedByCIFilterDealloc(PropImpl)) {

697

OS <<

"' will be released by '-[CIFilter dealloc]' but also released here"

;

699

OS <<

"' was synthesized for "

;

704

OS <<

"an assign, readwrite"

;

706

OS <<

" property but was released in 'dealloc'"

;

709 auto

BR = std::make_unique<PathSensitiveBugReport>(ExtraReleaseBugType, Buf,

713 C

.emitReport(std::move(BR));

721bool

ObjCDeallocChecker::diagnoseMistakenDealloc(

SymbolRef

DeallocedValue,

732

findPropertyOnDeallocatingInstance(DeallocedValue,

C

);

736 if

(getDeallocReleaseRequirement(PropImpl) !=

746

llvm::raw_string_ostream OS(Buf);

749

<<

"' should be released rather than deallocated"

;

751 auto

BR = std::make_unique<PathSensitiveBugReport>(MistakenDeallocBugType,

755 C

.emitReport(std::move(BR));

760void

ObjCDeallocChecker::initIdentifierInfoAndSelectors(

765

NSObjectII = &Ctx.

Idents

.

get

(

"NSObject"

);

766

SenTestCaseII = &Ctx.

Idents

.

get

(

"SenTestCase"

);

767

XCTestCaseII = &Ctx.

Idents

.

get

(

"XCTestCase"

);

768

Block_releaseII = &Ctx.

Idents

.

get

(

"_Block_release"

);

769

CIFilterII = &Ctx.

Idents

.

get

(

"CIFilter"

);

778bool

ObjCDeallocChecker::isSuperDeallocMessage(

788

ObjCDeallocChecker::getContainingObjCImpl(

const LocationContext

*LCtx)

const

{

789 auto

*MD = cast<ObjCMethodDecl>(LCtx->

getDecl

());

803 auto

*CatDecl = dyn_cast<ObjCCategoryDecl>(PropDecl->

getDeclContext

());

806 if

(!CatDecl || !CatDecl->IsClassExtension())

812 auto

*ShadowedPropDecl = dyn_cast<ObjCPropertyDecl>(

D

);

813 if

(!ShadowedPropDecl)

816 if

(ShadowedPropDecl->isInstanceProperty()) {

817

assert(ShadowedPropDecl->isReadOnly());

818 return

ShadowedPropDecl;

835

removeValueRequiringRelease(InitialState, InstanceSym,

Value

);

837 if

(ReleasedState != InitialState) {

838 C

.addTransition(ReleasedState);

852 const SymbolSet

*Unreleased = State->get<UnreleasedIvarMap>(Instance);

857

SymbolSet::Factory &F = State->getStateManager().get_context<

SymbolSet

>();

859 for

(

auto

&Sym : *Unreleased) {

860 const ObjCIvarRegion

*UnreleasedRegion = getIvarRegionForIvarSymbol(Sym);

861

assert(UnreleasedRegion);

862 if

(RemovedRegion->

getDecl

() == UnreleasedRegion->

getDecl

()) {

863

NewUnreleased = F.remove(NewUnreleased, Sym);

867 if

(NewUnreleased.isEmpty()) {

868 return

State->remove<UnreleasedIvarMap>(Instance);

871 return

State->set<UnreleasedIvarMap>(Instance, NewUnreleased);

890 if

(isReleasedByCIFilterDealloc(PropImpl))

893 if

(isNibLoadedIvarWithoutRetain(PropImpl))

910

llvm_unreachable(

"Unrecognized setter kind"

);

916

ObjCDeallocChecker::getValueReleasedByNillingOut(

const ObjCMethodCall

&M,

931

std::tie(notNilState, nilState) =

933 if

(!(nilState && !notNilState))

946 SVal

LVal = State->getLValue(PropIvarDecl, ReceiverVal);

947

std::optional<Loc> LValLoc = LVal.

getAs

<

Loc

>();

951 SVal

CurrentValInIvar = State->getSVal(*LValLoc);

958bool

ObjCDeallocChecker::isInInstanceDealloc(

const CheckerContext

&

C

,

959 SVal

&SelfValOut)

const

{

960 return

isInInstanceDealloc(

C

,

C

.getLocationContext(), SelfValOut);

966bool

ObjCDeallocChecker::isInInstanceDealloc(

const CheckerContext

&

C

,

968 SVal

&SelfValOut)

const

{

969 auto

*MD = dyn_cast<ObjCMethodDecl>(LCtx->

getDecl

());

974

assert(SelfDecl &&

"No self in -dealloc?"

);

977

SelfValOut = State->getSVal(State->getRegion(SelfDecl, LCtx));

984bool

ObjCDeallocChecker::instanceDeallocIsOnStack(

const CheckerContext

&

C

,

985 SVal

&InstanceValOut)

const

{

989 if

(isInInstanceDealloc(

C

, LCtx, InstanceValOut))

1001bool

ObjCDeallocChecker::classHasSeparateTeardown(

1004 for

( ;

ID

;

ID

=

ID

->getSuperClass()) {

1007 if

(II == NSObjectII)

1014 if

(II == XCTestCaseII || II == SenTestCaseII)

1029bool

ObjCDeallocChecker::isReleasedByCIFilterDealloc(

1035 const char

*ReleasePrefix =

"input"

;

1036 if

(!(PropName.starts_with(ReleasePrefix) ||

1037

IvarName.starts_with(ReleasePrefix))) {

1043 for

( ;

ID

;

ID

=

ID

->getSuperClass()) {

1045 if

(II == CIFilterII)

1060bool

ObjCDeallocChecker::isNibLoadedIvarWithoutRetain(

1063 if

(!IvarDecl->

hasAttr

<IBOutletAttr>())

1066 const

llvm::Triple &

Target

=

1069 if

(!

Target

.isMacOSX())

1082bool

ento::shouldRegisterObjCDeallocChecker(

const CheckerManager

&mgr) {

1085 return

LO.getGC() != LangOptions::GCOnly && !LO.ObjCAutoRefCount;

static const MemRegion * getRegion(const CallEvent &Call, const MutexDescriptor &Descriptor, bool IsLock)

ReleaseRequirement

Indicates whether an instance variable is required to be released in -dealloc.

@ MustNotReleaseDirectly

The instance variable must not be directly released with -release.

@ Unknown

The requirement for the instance variable could not be determined.

@ MustRelease

The instance variable must be released, either by calling -release on it directly or by nilling it ou...

static bool isSynthesizedRetainableProperty(const ObjCPropertyImplDecl *I, const ObjCIvarDecl **ID, const ObjCPropertyDecl **PD)

Returns true if the property implementation is synthesized and the type of the property is retainable...

Defines the clang::LangOptions interface.

llvm::MachO::SymbolSet SymbolSet

llvm::MachO::Target Target

#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)

Declares an immutable map of type NameTy, suitable for placement into the ProgramState.

#define REGISTER_SET_FACTORY_WITH_PROGRAMSTATE(Name, Elem)

Declares an immutable set type Name and registers the factory for such sets in the program state,...

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

SelectorTable & Selectors

const TargetInfo & getTargetInfo() const

The results of name lookup within a DeclContext.

ASTContext & getASTContext() const LLVM_READONLY

DeclContext * getDeclContext()

One of these records is kept for each identifier that is lexed.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

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

const LocationContext * getParent() const

It might return null.

virtual bool inTopFrame() const

const ImplicitParamDecl * getSelfDecl() const

This represents a decl that may have a name.

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

ObjCPropertyImplDecl * FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const

FindPropertyImplIvarDecl - This method lookup the ivar in the list of properties implemented in this ...

ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...

Represents an ObjC class declaration.

ObjCIvarDecl - Represents an ObjC instance variable.

ObjCInterfaceDecl * getContainingInterface()

Return the class interface that this ivar is logically contained in; this is either the interface whe...

@ SuperInstance

The receiver is the instance of the superclass object.

ReceiverKind getReceiverKind() const

Determine the kind of receiver that this message is being sent to.

ObjCMethodDecl - Represents an instance or class method declaration.

Selector getSelector() const

bool isInstanceMethod() const

Represents one property declaration in an Objective-C interface.

ObjCMethodDecl * getSetterMethodDecl() const

bool isReadOnly() const

isReadOnly - Return true iff the property has a setter.

ObjCIvarDecl * getPropertyIvarDecl() const

SetterKind getSetterKind() const

getSetterKind - Return the method used for doing assignment in the property setter.

ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...

ObjCIvarDecl * getPropertyIvarDecl() const

Kind getPropertyImplementation() const

ObjCPropertyDecl * getPropertyDecl() const

A (possibly-)qualified type.

ReturnStmt - This represents a return, optionally of an expression: return; return 4;.

Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)

Can create any sort of selector.

Smart pointer class that efficiently represents Objective-C method names.

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

bool isObjCRetainableType() const

const LangOptions & getLangOpts() const

ASTContext & getASTContext() override

BugReporter is a utility class for generating PathDiagnostics for analysis.

const SourceManager & getSourceManager()

void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges={}, ArrayRef< FixItHint > Fixits={})

Represents an abstract call to a function or method along a particular path.

const ProgramStateRef & getState() const

The state in which the call is being evaluated.

virtual SVal getArgSVal(unsigned Index) const

Returns the value of a given argument at the time of the call.

CHECKER * registerChecker(AT &&... Args)

Used to register checkers.

const LangOptions & getLangOpts() const

MemRegion - The root abstract class for all memory regions.

const SymbolicRegion * getSymbolicBase() const

If this is a symbolic region, returns the region.

LLVM_ATTRIBUTE_RETURNS_NONNULL const ObjCIvarDecl * getDecl() const override

Represents any expression that calls an Objective-C method.

const Expr * getArgExpr(unsigned Index) const override

Returns the expression associated with a given argument.

unsigned getNumArgs() const override

Returns the number of arguments (explicit and implicit).

const ObjCMessageExpr * getOriginExpr() const override

Returns the expression whose value will be the result of this call.

SVal getReceiverSVal() const

Returns the value of the receiver at the time of this call.

bool isReceiverSelfOrSuper() const

Checks if the receiver refers to 'self' or 'super'.

Selector getSelector() const

const ObjCPropertyDecl * getAccessedProperty() const

static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)

Create a location for the beginning of the declaration.

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.

T castAs() const

Convert to the specified SVal type, asserting that this SVal is of the desired type.

LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getSuperRegion() const

virtual const MemRegion * getOriginRegion() const

Find the region from which this symbol originates.

SymbolicRegion - A special, "non-concrete" region.

SymbolRef getSymbol() const

It might return null.

TypedValueRegion - An abstract class representing regions having a typed value.

LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getRegion() const

Get the underlining region.

Defines the clang::TargetInfo interface.

const char *const CoreFoundationObjectiveC

const char *const MemoryRefCount

PointerEscapeKind

Describes the different reasons a pointer escapes during analysis.

llvm::DenseSet< SymbolRef > InvalidatedSymbols

The JSON file list parser is used to communicate input to InstallAPI.

const FunctionProtoType * T

@ Interface

The "__interface" keyword introduces the elaborated-type-specifier.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4