A RetroSearch Logo

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

Search Query:

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

clang: lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp Source File

16#include "llvm/ADT/STLExtras.h" 17#include "llvm/ADT/SmallVector.h" 20using namespace clang

;

22using namespace

retaincountchecker;

27 return "Use-after-release"

;

29 return "Bad release"

;

31 return "-dealloc sent to non-exclusively owned object"

;

33 return "freeing non-exclusively owned object"

;

35 return "Object autoreleased too many times"

;

37 return "Method should return an owned object"

;

41 return "Leak of returned object"

;

43

llvm_unreachable(

"Unknown RefCountBugKind"

);

49 return "Reference-counted object is used after it is released"

;

51 return "Incorrect decrement of the reference count of an object that is " 52 "not owned at this point by the caller"

;

54 return "-dealloc sent to object that may be referenced elsewhere"

;

56 return "'free' called on an object that may be referenced elsewhere"

;

58 return "Object autoreleased too many times"

;

60 return "Object with a +0 retain count returned to caller where a +1 " 61 "(owning) retain count is expected"

;

66

llvm_unreachable(

"Unknown RefCountBugKind"

);

70

:

BugType

(

Checker

, bugTypeToName(BT), categories::MemoryRefCount,

71

BT == LeakWithinFunction ||

88 return

std::string(RD->getName());

104

assert(!PrevV.

hasSameState

(CurrV) &&

"The state should have changed."

);

109

os <<

"Object released by directly sending the '-dealloc' message"

;

125

os <<

"Object autoreleased"

;

130

os <<

"Reference count decremented."

;

132

os <<

"Reference count incremented."

;

134 if

(

unsigned

Count = CurrV.

getCount

())

135

os <<

" The object now has a +"

<< Count <<

" retain count."

;

143

os <<

"Strong instance variable relinquished. "

;

145

os <<

"Object released."

;

153

os <<

"Object returned to caller as an owning reference (single " 154 "retain count transferred to caller)"

;

158

os <<

"Object returned to caller with a +0 retain count"

;

170static

std::optional<unsigned>

176 for

(

unsigned

Idx = 0; Idx < (*CE)->getNumArgs(); Idx++)

177 if

(

const MemRegion

*MR = (*CE)->getArgSVal(Idx).getAsRegion())

178 if

(

const auto

*TR = dyn_cast<TypedValueRegion>(MR))

179 if

(CurrSt->getSVal(MR, TR->getValueType()).getAsSymbol() == Sym)

186 if

(

const auto

*ME = dyn_cast<MemberExpr>(Callee)) {

187 if

(ME->getMemberDecl()->getNameAsString() !=

"alloc"

)

189 const Expr

*This = ME->getBase()->IgnoreParenImpCasts();

190 if

(

const auto

*DRE = dyn_cast<DeclRefExpr>(This)) {

195 if

(

const auto

*RD = dyn_cast<CXXRecordDecl>(VD->

getDeclContext

()))

204 if

(

const auto

*CE = dyn_cast<CallExpr>(S))

214

llvm::raw_string_ostream &os) {

216 if

(

const CallExpr

*CE = dyn_cast<CallExpr>(S)) {

219 SVal X

= CurrSt->getSValAsScalarOrLoc(CE->getCallee(), LCtx);

224

FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());

226 if

(

const auto

*MD = dyn_cast<CXXMethodDecl>(CE->getCalleeDecl())) {

227

os <<

"Call to method '"

<< MD->getQualifiedNameAsString() <<

'\''

;

231

os <<

"function call"

;

233

}

else if

(isa<CXXNewExpr>(S)) {

234

os <<

"Operator 'new'"

;

236

assert(isa<ObjCMessageExpr>(S));

238

cast<ObjCMessageExpr>(S), CurrSt, LCtx, {

nullptr

, 0});

240 switch

(

Call

->getMessageKind()) {

253

std::optional<CallEventRef<>> CE = Mgr.

getCall

(S, CurrSt, LCtx, {

nullptr

, 0});

264

os <<

"a Core Foundation object of type '"

<< Sym->

getType

() <<

"' with a "

;

269

os <<

"an object of type '"

<< Sym->

getType

() <<

"' with a "

;

273 if

(!isa<ObjCObjectPointerType>(

T

)) {

274

os <<

"an Objective-C object with a "

;

282

os <<

"+1 retain count"

;

285

os <<

"+0 retain count"

;

289

os <<

" into an out parameter '"

;

290 const ParmVarDecl

*PVD = (*CE)->parameters()[*Idx];

295 QualType

RT = (*CE)->getResultType();

297 SVal

RV = (*CE)->getReturnValue();

298 if

(CurrSt->isNull(RV).isConstrainedTrue()) {

299

os <<

" (assuming the call returns zero)"

;

300

}

else if

(CurrSt->isNonNull(RV).isConstrainedTrue()) {

301

os <<

" (assuming the call returns non-zero)"

;

310namespace

retaincountchecker {

319 void Profile

(llvm::FoldingSetNodeID &

ID

)

const override

{

372static

std::shared_ptr<PathDiagnosticEventPiece>

385

llvm::raw_string_ostream os(sbuf);

387 for

(

unsigned

I=0; I <

Call

->getNumArgs() && I < Parameters.size(); ++I) {

390 if

(!PVD->

hasAttr

<OSConsumedAttr>())

397 if

(!CountBeforeCall || !CountAtExit)

400 unsigned

CountBefore = CountBeforeCall->

getCount

();

401 unsigned

CountAfter = CountAtExit->

getCount

();

403 bool

AsExpected = CountBefore > 0 && CountAfter == CountBefore - 1;

405

os <<

"Parameter '"

;

408

os <<

"' is marked as consuming, but the function did not consume " 409

<<

"the reference\n"

;

418 return

std::make_shared<PathDiagnosticEventPiece>(L, sbuf);

422static

std::shared_ptr<PathDiagnosticEventPiece>

436 const auto

*VR = cast<VarRegion>(cast<SymbolRegionValue>(Sym)->

getRegion

());

437 const auto

*PVD = cast<ParmVarDecl>(VR->getDecl());

441

llvm::raw_string_ostream os(

s

);

442

os <<

"Parameter '"

<< PVD->getDeclName() <<

"' starts at +"

;

444

os <<

"1, as it is marked as consuming"

;

449 return

std::make_shared<PathDiagnosticEventPiece>(L,

s

);

485 const RefVal

&CurrV = *CurrT;

491

llvm::raw_string_ostream os(sbuf);

494

os <<

"Object is now not exclusively owned"

;

496 return

std::make_shared<PathDiagnosticEventPiece>(Pos, sbuf);

504 if

(isa<ObjCIvarRefExpr>(S) &&

509 if

(isa<ObjCArrayLiteral>(S)) {

510

os <<

"NSArray literal is an object with a +0 retain count"

;

511

}

else if

(isa<ObjCDictionaryLiteral>(S)) {

512

os <<

"NSDictionary literal is an object with a +0 retain count"

;

513

}

else if

(

const ObjCBoxedExpr

*BL = dyn_cast<ObjCBoxedExpr>(S)) {

515

os <<

"NSNumber literal is an object with a +0 retain count"

;

519

BoxClass = Method->getClassInterface();

524

os << *BoxClass <<

" b"

;

529

os <<

"oxed expression produces an object with a +0 retain count"

;

531

}

else if

(isa<ObjCIvarRefExpr>(S)) {

532

os <<

"Object loaded from instance variable"

;

538 return

std::make_shared<PathDiagnosticEventPiece>(Pos, sbuf);

543 bool

DeallocSent =

false

;

548

os <<

"Assuming dynamic cast returns null due to type mismatch"

;

556 if

(

const CallExpr

*CE = dyn_cast<CallExpr>(S)) {

561 for

(

auto

AI=CE->arg_begin(), AE=CE->arg_end(); AI!=AE; ++AI, ++i) {

565 if

(CurrSt->getSValAsScalarOrLoc(*AI, LCtx).getAsLocSymbol() !=

Sym

)

571

}

else if

(

const ObjCMessageExpr

*ME = dyn_cast<ObjCMessageExpr>(S)) {

572 if

(

const Expr

*receiver = ME->getInstanceReceiver()) {

573 if

(CurrSt->getSValAsScalarOrLoc(receiver, LCtx)

574

.getAsLocSymbol() ==

Sym

) {

591 auto P

= std::make_shared<PathDiagnosticEventPiece>(Pos, sbuf);

595 for

(

const Stmt

*Child : S->children())

596 if

(

const Expr

*Exp = dyn_cast_or_null<Expr>(Child))

597 if

(CurrSt->getSValAsScalarOrLoc(Exp, LCtx).getAsLocSymbol() ==

Sym

) {

598 P

->addRange(Exp->getSourceRange());

602 return

std::move(

P

);

606 if

(

const auto

*VR = dyn_cast_or_null<VarRegion>(MR))

607 return

std::string(VR->getDecl()->getName());

622

: Sym(Sym), Result(ToFill) {}

627 if

(!SymV || SymV != Sym)

630 if

(isa<NonParamVarRegion>(R))

631

Result.emplace_back(R, Val);

642

VarBindingsCollector Collector{Sym,

Result

};

657struct

AllocationInfo {

664

N(InN), R(InR), InterestingMethodContext(InInterestingMethodContext) {}

671 const ExplodedNode

*AllocationNodeInCurrentOrParentContext = N;

672 const MemRegion

*FirstBinding =

nullptr

;

708 if

(NContext == LeakContext || NContext->

isParentOf

(LeakContext))

709

AllocationNodeInCurrentOrParentContext = N;

713 if

(!InitMethodContext)

715 const Stmt

*CE = CEP->getCallExpr();

716 if

(

const auto

*ME = dyn_cast_or_null<ObjCMessageExpr>(CE)) {

717 const Stmt

*RecExpr = ME->getInstanceReceiver();

719 SVal

RecV = St->getSVal(RecExpr, NContext);

721

InitMethodContext = CEP->getCalleeContext();

732 if

(InitMethodContext) {

737

InterestingMethodContext = InitMethodContext;

742

assert(N &&

"Could not find allocation node"

);

744 if

(AllocationNodeInCurrentOrParentContext &&

747

FirstBinding =

nullptr

;

749 return

AllocationInfo(AllocationNodeInCurrentOrParentContext, FirstBinding,

750

InterestingMethodContext);

773

llvm::raw_string_ostream os(sbuf);

775

os <<

"Object leaked: "

;

777

std::optional<std::string> RegionDescription =

describeRegion

(LastBinding);

778 if

(RegionDescription) {

779

os <<

"object allocated and stored into '"

<< *RegionDescription <<

'\''

;

792

os << (isa<ObjCMethodDecl>(

D

) ?

" is returned from a method " 793

:

" is returned from a function "

);

795 if

(

D

->

hasAttr

<CFReturnsNotRetainedAttr>()) {

796

os <<

"that is annotated as CF_RETURNS_NOT_RETAINED"

;

797

}

else if

(

D

->

hasAttr

<NSReturnsNotRetainedAttr>()) {

798

os <<

"that is annotated as NS_RETURNS_NOT_RETAINED"

;

799

}

else if

(

D

->

hasAttr

<OSReturnsNotRetainedAttr>()) {

800

os <<

"that is annotated as OS_RETURNS_NOT_RETAINED"

;

804

os <<

"managed by Automatic Reference Counting"

;

806

os <<

"whose name ('"

<< MD->getSelector().getAsString()

807

<<

"') does not start with " 808 "'copy', 'mutableCopy', 'alloc' or 'new'." 809 " This violates the naming convention rules" 810 " given in the Memory Management Guide for Cocoa"

;

816

os <<

"whose name ('"

<< *FD

817

<<

"') does not contain 'Copy' or 'Create'. This violates the " 819 " convention rules given in the Memory Management Guide for " 824

os <<

"whose name ('"

<< FuncName <<

"') starts with '" 825

<< StringRef(FuncName).substr(0, 3) <<

"'"

;

830

os <<

" is not referenced later in this execution path and has a retain " 835 return

std::make_shared<PathDiagnosticEventPiece>(L, sbuf);

843

addVisitor<RefCountReportVisitor>(sym);

851

addVisitor<RefCountReportVisitor>(sym);

862 const Decl

*PDecl = Region->getDecl();

863 if

(isa_and_nonnull<ParmVarDecl>(PDecl)) {

866

Location = ParamLocation;

886

AllocationInfo AllocI =

889

AllocNode = AllocI.N;

890

AllocFirstBinding = AllocI.R;

900

AllocFirstBinding =

nullptr

;

906

Location = AllocLocation;

918

os <<

"Potential leak of an object"

;

920

std::optional<std::string> RegionDescription =

922 if

(RegionDescription) {

923

os <<

" stored into '"

<< *RegionDescription <<

'\''

;

933 if

(!AllocFirstBinding)

939 if

(

Node

->getState()->getSVal(AllocFirstBinding).getAsSymbol() ==

Sym

) {

941

AllocBindingToReport = AllocFirstBinding;

964 if

(!AllVarBindings.empty() &&

965

llvm::count_if(AllVarBindings,

966

[

this

](

const

std::pair<const MemRegion *, SVal> Binding) {

967

return Binding.first == AllocFirstBinding;

970

AllocBindingToReport = AllVarBindings[0].first;

982

AllocBindingToReport, *

this

);

984

AllocBindingToReport = AllocFirstBinding;

993

deriveAllocLocation(Ctx);

994

findBindingToReport(Ctx, N);

996 if

(!AllocFirstBinding)

997

deriveParamLocation(Ctx);

999

createDescription(Ctx);

1001

addVisitor<RefLeakReportVisitor>(

Sym

, AllocBindingToReport);

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

static std::shared_ptr< PathDiagnosticEventPiece > annotateStartParameter(const ExplodedNode *N, SymbolRef Sym, const SourceManager &SM)

Annotate the parameter at the analysis entry point.

static std::string getPrettyTypeName(QualType QT)

If type represents a pointer to CXXRecordDecl, and is not a typedef, return the decl name.

static bool shouldGenerateNote(llvm::raw_string_ostream &os, const RefVal *PrevT, const RefVal &CurrV, bool DeallocSent)

Write information about the type state change to os, return whether the note should be generated.

static bool isNumericLiteralExpression(const Expr *E)

static std::optional< unsigned > findArgIdxOfSymbol(ProgramStateRef CurrSt, const LocationContext *LCtx, SymbolRef &Sym, std::optional< CallEventRef<> > CE)

Finds argument index of the out paramter in the call S corresponding to the symbol Sym.

static std::shared_ptr< PathDiagnosticEventPiece > annotateConsumedSummaryMismatch(const ExplodedNode *N, CallExitBegin &CallExitLoc, const SourceManager &SM, CallEventManager &CEMgr)

Insert a diagnostic piece at function exit if a function parameter is annotated as "os_consumed",...

static std::string findAllocatedObjectName(const Stmt *S, QualType QT)

static AllocationInfo GetAllocationSite(ProgramStateManager &StateMgr, const ExplodedNode *N, SymbolRef Sym)

static std::optional< std::string > describeRegion(const MemRegion *MR)

static std::optional< std::string > findMetaClassAlloc(const Expr *Callee)

static const ExplodedNode * getCalleeNode(const ExplodedNode *Pred)

Find the first node with the parent stack frame.

static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt, const LocationContext *LCtx, const RefVal &CurrV, SymbolRef &Sym, const Stmt *S, llvm::raw_string_ostream &os)

static Bindings getAllVarBindingsForSymbol(ProgramStateManager &Manager, const ExplodedNode *Node, SymbolRef Sym)

__device__ __2f16 float __ockl_bool s

SourceManager & getSourceManager()

const LangOptions & getLangOpts() const

const clang::PrintingPolicy & getPrintingPolicy() const

Represents a single basic block in a source-level CFG.

A boolean literal, per ([C++ lex.bool] Boolean literals).

Represents a point when we begin processing an inlined call.

Represents a point when we start the call exit sequence (for inlined call).

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

Decl - This represents one declaration (or definition), e.g.

ASTContext & getASTContext() const LLVM_READONLY

DeclContext * getDeclContext()

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 ...

bool isParentOf(const LocationContext *LC) const

const Decl * getDecl() const

const LocationContext * getParent() const

It might return null.

const StackFrameContext * getStackFrame() const

std::string getQualifiedNameAsString() const

std::string getNameAsString() const

Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...

virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const

Appends a human-readable name for this declaration into the given stream.

ObjCBoolLiteralExpr - Objective-C Boolean Literal.

ObjCBoxedExpr - used for generalized expression boxing.

Represents an ObjC class declaration.

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.

QualType getPointeeType() const

Gets the type pointed to by this ObjC pointer.

Represents a parameter to a function.

ProgramPoints can be "tagged" as representing points specific to a given analysis entity.

const ProgramPointTag * getTag() const

T castAs() const

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

std::optional< T > getAs() const

Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...

A (possibly-)qualified type.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)

This class handles loading and caching of source files into memory.

It represents a stack frame of the call stack (based on CallEvent).

const Stmt * getCallSite() const

bool inTopFrame() const override

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...

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

const T * getAs() const

Member-template getAs<specific type>'.

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

const BugType & getBugType() const

ASTContext & getASTContext() const

ProgramStateManager & getStateManager() const

const SourceManager & getSourceManager() const

BugReporterVisitors are used to add custom diagnostics along a path.

static PathDiagnosticPieceRef getDefaultEndPath(const BugReporterContext &BRC, const ExplodedNode *N, const PathSensitiveBugReport &BR)

Generates the default final diagnostic piece.

Manages the lifetime of CallEvent objects.

CallEventRef getCall(const Stmt *S, ProgramStateRef State, const LocationContext *LC, CFGBlock::ConstCFGElementRef ElemRef)

Gets a call event for a function call, Objective-C method call, a 'new', or a 'delete' call.

CallEventRef< ObjCMethodCall > getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)

CallEventRef getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State)

Gets an outside caller given a callee context.

This wrapper is used to ensure that only StringRefs originating from the CheckerRegistry are used as ...

const ProgramStateRef & getState() const

const Stmt * getStmtForDiagnostics() const

If the node's program point corresponds to a statement, retrieve that statement.

ProgramPoint getLocation() const

getLocation - Returns the edge associated with the given node.

const StackFrameContext * getStackFrame() const

const LocationContext * getLocationContext() const

std::optional< T > getLocationAs() const &

ExplodedNode * getFirstPred()

const Decl & getCodeDecl() const

MemRegion - The root abstract class for all memory regions.

LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace() const

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

Create a location for the beginning of the declaration.

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

Create a location corresponding to the given declaration.

void markInteresting(SymbolRef sym, bugreporter::TrackingKind TKind=bugreporter::TrackingKind::Thorough)

Marks a symbol as interesting.

PathDiagnosticLocation UniqueingLocation

Reports with different uniqueing locations are considered to be different for the purposes of dedupli...

const ExplodedNode * getErrorNode() const

const Decl * UniqueingDecl

CallEventManager & getCallEventManager()

void iterBindings(ProgramStateRef state, StoreManager::BindingsHandler &F)

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.

SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const

If this SVal is a location and wraps a symbol, return that SymbolRef.

const MemRegion * getRegion()

virtual const MemRegion * getOriginRegion() const

Find the region from which this symbol originates.

virtual QualType getType() const =0

RefCountBug(CheckerNameRef Checker, RefCountBugKind BT)

StringRef getDescription() const

RefCountBugKind getBugType() const

void Profile(llvm::FoldingSetNodeID &ID) const override

PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override

Return a diagnostic piece which should be associated with the given node.

PathDiagnosticPieceRef getEndPath(BugReporterContext &BRC, const ExplodedNode *N, PathSensitiveBugReport &BR) override

Provide custom definition for the final diagnostic piece on the path - the piece, which is displayed ...

RefCountReportVisitor(SymbolRef sym)

RefCountReport(const RefCountBug &D, const LangOptions &LOpts, ExplodedNode *n, SymbolRef sym, bool isLeak=false)

RefLeakReportVisitor(SymbolRef Sym, const MemRegion *LastBinding)

PathDiagnosticPieceRef getEndPath(BugReporterContext &BRC, const ExplodedNode *N, PathSensitiveBugReport &BR) override

Provide custom definition for the final diagnostic piece on the path - the piece, which is displayed ...

RefLeakReport(const RefCountBug &D, const LangOptions &LOpts, ExplodedNode *n, SymbolRef sym, CheckerContext &Ctx)

unsigned getCount() const

unsigned getCombinedCounts() const

@ ReleasedAfterDirectAccess

IvarAccessHistory getIvarAccessHistory() const

Returns what the analyzer knows about direct accesses to a particular instance variable.

unsigned getAutoreleaseCount() const

bool hasSameState(const RefVal &X) const

ObjKind getObjKind() const

static const CheckerProgramPointTag & getCastFailTag()

static const CheckerProgramPointTag & getDeallocSentTag()

void trackStoredValue(SVal V, const MemRegion *R, PathSensitiveBugReport &Report, TrackingOptions Opts={}, const StackFrameContext *Origin=nullptr)

Track how the value got stored into the given region and where it came from.

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...

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.

const void * Store

Store - This opaque type encapsulates an immutable mapping from locations to values.

std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef

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

bool isa(CodeGen::Address addr)

@ Result

The result type of a method or function.

const FunctionProtoType * T


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