26 #include "llvm/Support/raw_ostream.h"
28 using namespace clang;
39 if (ME->getSelector() == Release)
40 if (ME->getInstanceReceiver())
43 if (E->getDecl() ==
ID)
48 if (ME->getInstanceReceiver())
50 if (
DeclRefExpr *E = dyn_cast<DeclRefExpr>(Receiver))
51 if (E->getDecl()->getIdentifier() == SelfII)
53 ME->getNumArgs() == 1 &&
54 ME->getArg(0)->isNullPointerConstant(Ctx,
60 if (BO->isAssignmentOp())
62 dyn_cast<ObjCPropertyRefExpr>(BO->getLHS()->IgnoreParenCasts()))
63 if (PRE->isExplicitProperty() && PRE->getExplicitProperty() == PD)
64 if (BO->getRHS()->isNullPointerConstant(Ctx,
72 for (
Stmt *SubStmt : S->children())
93 bool containsPointerIvar =
false;
95 for (
const auto *Ivar : ID->
ivars()) {
99 Ivar->hasAttr<IBOutletAttr>() ||
100 Ivar->hasAttr<IBOutletCollectionAttr>())
103 containsPointerIvar =
true;
107 if (!containsPointerIvar)
118 if (II == NSObjectII)
125 if (II == SenTestCaseII)
134 Selector S = Ctx.Selectors.getSelector(0, &II);
139 if (I->getSelector() ==
S) {
152 :
"missing -dealloc (Hybrid MM, non-GC)";
155 llvm::raw_string_ostream os(buf);
156 os <<
"Objective-C class '" << *D <<
"' lacks a 'dealloc' instance method";
165 Selector RS = Ctx.Selectors.getSelector(0, &RII);
196 != requiresRelease) {
197 const char *name =
nullptr;
199 llvm::raw_string_ostream os(buf);
201 if (requiresRelease) {
203 ?
"missing ivar release (leak)"
204 :
"missing ivar release (Hybrid MM, non-GC)";
207 <<
"' instance variable was retained by a synthesized property but "
208 "wasn't released in 'dealloc'";
211 ?
"extra ivar release (use-after-release)"
212 :
"extra ivar release (Hybrid MM, non-GC)";
215 <<
"' instance variable was not retained by a synthesized property "
216 "but was released in 'dealloc'";
233 class ObjCDeallocChecker :
public Checker<
234 check::ASTDecl<ObjCImplementationDecl> > {
const char *const CoreFoundationObjectiveC
Smart pointer class that efficiently represents Objective-C method names.
IdentifierInfo * getIdentifier() const
static bool scan_ivar_release(Stmt *S, ObjCIvarDecl *ID, const ObjCPropertyDecl *PD, Selector Release, IdentifierInfo *SelfII, ASTContext &Ctx)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static void checkObjCDealloc(const CheckerBase *Checker, const ObjCImplementationDecl *D, const LangOptions &LOpts, BugReporter &BR)
ASTContext & getContext()
A builtin binary operation expression such as "x + y" or "x <= y".
Expr * IgnoreParenCasts() LLVM_READONLY
Represents an ObjC class declaration.
propimpl_range property_impls() const
ID
Defines the set of possible language-specific address spaces.
Defines the clang::LangOptions interface.
SetterKind getSetterKind() const
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
An expression that sends a message to the given Objective-C object or class.
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
CHECKER * registerChecker()
Used to register checkers.
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges=None)
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
const ObjCInterfaceDecl * getClassInterface() const
Represents one property declaration in an Objective-C interface.
instmeth_range instance_methods() const
ObjCMethodDecl * getSetterMethodDecl() const
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceManager & getSourceManager()
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
bool isObjCObjectPointerType() const
ObjCInterfaceDecl * getSuperClass() const
const LangOptions & getLangOpts() const
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].