37 using namespace clang;
43 const char * RunLoopBind =
"NSRunLoopM";
44 const char * RunLoopRunBind =
"RunLoopRunM";
45 const char * OtherMsgBind =
"OtherMessageSentM";
46 const char * AutoreleasePoolBind =
"AutoreleasePoolM";
47 const char * OtherStmtAutoreleasePoolBind =
"OtherAutoreleasePoolM";
49 class RunLoopAutoreleaseLeakChecker :
public Checker<check::ASTCodeBody> {
52 void checkASTCodeBody(
const Decl *D,
54 BugReporter &BR)
const;
75 return seenBefore(C, A, B);
84 const RunLoopAutoreleaseLeakChecker *Checker) {
98 bool HasAutoreleasePool = (AP !=
nullptr);
102 assert(RLR &&
"Run loop launch not found");
106 if (seenBefore(DeclBody, RLR, ME))
109 if (HasAutoreleasePool && (OAP != AP))
113 ME, BR.getSourceManager(), ADC);
116 BR.EmitBasicReport(ADC->
getDecl(), Checker,
117 "Memory leak inside autorelease pool",
120 (Twine(
"Temporary objects allocated in the") +
121 " autorelease pool " +
122 (HasAutoreleasePool ?
"" :
"of last resort ") +
123 "followed by the launch of " +
124 (RL ?
"main run loop " :
"xpc_main ") +
125 "may never get released; consider moving them to a " 126 "separate autorelease pool")
134 hasReceiverType(asString(
"NSRunLoop")),
139 hasReceiver(MainRunLoopM),
140 Extra).bind(RunLoopRunBind);
144 return anyOf(MainRunLoopRunM, XPCRunM);
149 equalsBoundNode(RunLoopRunBind))),
155 checkTempObjectsInSamePool(
const Decl *D, AnalysisManager &AM, BugReporter &BR,
156 const RunLoopAutoreleaseLeakChecker *Chkr) {
174 checkTempObjectsInNoPool(
const Decl *D, AnalysisManager &AM, BugReporter &BR,
175 const RunLoopAutoreleaseLeakChecker *Chkr) {
195 void RunLoopAutoreleaseLeakChecker::checkASTCodeBody(
const Decl *D,
197 BugReporter &BR)
const {
198 checkTempObjectsInSamePool(D, AM, BR,
this);
199 checkTempObjectsInNoPool(D, AM, BR,
this);
202 void ento::registerRunLoopAutoreleaseLeakChecker(CheckerManager &mgr) {
203 mgr.registerChecker<RunLoopAutoreleaseLeakChecker>();
206 bool ento::shouldRegisterRunLoopAutoreleaseLeakChecker(
const LangOptions &LO) {
internal::TrueMatcher anything()
Matches any node.
const internal::VariadicDynCastAllOfMatcher< Stmt, CallExpr > callExpr
Matches call expressions.
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Stmt - This represents one statement.
internal::Matcher< Stmt > StatementMatcher
const internal::VariadicOperatorMatcherFunc< 2, std::numeric_limits< unsigned >::max()> anyOf
Matches if any of the given matchers matches.
Decl - This represents one declaration (or definition), e.g.
const internal::ArgumentAdaptingMatcherFunc< internal::HasDescendantMatcher > hasDescendant
Matches AST nodes that have descendant AST nodes that match the provided matcher. ...
const internal::VariadicDynCastAllOfMatcher< Decl, FunctionDecl > functionDecl
Matches function declarations.
AnalysisDeclContext contains the context data for the function or method under analysis.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
const T * getNodeAs(StringRef ID) const
Returns the AST node bound to ID.
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
const internal::VariadicDynCastAllOfMatcher< Stmt, ObjCAutoreleasePoolStmt > autoreleasePoolStmt
Matches an Objective-C autorelease pool statement.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
An expression that sends a message to the given Objective-C object or class.
const internal::ArgumentAdaptingMatcherFunc< internal::HasAncestorMatcher, internal::TypeList< Decl, NestedNameSpecifierLoc, Stmt, TypeLoc >, internal::TypeList< Decl, NestedNameSpecifierLoc, Stmt, TypeLoc > > hasAncestor
Matches AST nodes that have an ancestor that matches the provided matcher.
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
Maps string IDs to AST nodes matched by parts of a matcher.
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
ASTContext & getASTContext() const LLVM_READONLY
const Decl * getDecl() const
static void emitDiagnostics(BoundNodes &Match, const Decl *D, BugReporter &BR, AnalysisManager &AM, const ObjCAutoreleaseWriteChecker *Checker)
const internal::VariadicOperatorMatcherFunc< 1, 1 > unless
Matches if the provided matcher does not match.
Dataflow Directional Tag Classes.
internal::Matcher< NamedDecl > hasName(const std::string &Name)
Matches NamedDecl nodes that have the specified name.
A trivial tuple used to represent a source range.
const internal::VariadicDynCastAllOfMatcher< Stmt, ObjCMessageExpr > objcMessageExpr
Matches ObjectiveC Message invocation expressions.
Represents Objective-C's @autoreleasepool Statement.
internal::Matcher< Decl > DeclarationMatcher
Types of matchers for the top-level classes in the AST class hierarchy.