blob: 3c5076391afd68101075dc95fe3b494ea1c99b40 [file] [log] [blame]
George Karpenkov70c2ee32018-08-17 21:41:07 +00001//==--- RetainCountChecker.h - Checks for leaks and other issues -*- C++ -*--//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the methods for RetainCountChecker, which implements
11// a reference count checker for Core Foundation and Cocoa on (Mac OS X).
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_H
16#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_H
17
18#include "../ClangSACheckers.h"
George Karpenkov70c2ee32018-08-17 21:41:07 +000019#include "RetainCountDiagnostics.h"
20#include "clang/AST/Attr.h"
21#include "clang/AST/DeclCXX.h"
22#include "clang/AST/DeclObjC.h"
23#include "clang/AST/ParentMap.h"
24#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
25#include "clang/Basic/LangOptions.h"
26#include "clang/Basic/SourceManager.h"
George Karpenkovefef49c2018-08-21 03:09:02 +000027#include "clang/Analysis/SelectorExtras.h"
George Karpenkov70c2ee32018-08-17 21:41:07 +000028#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
29#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
30#include "clang/StaticAnalyzer/Core/Checker.h"
31#include "clang/StaticAnalyzer/Core/CheckerManager.h"
32#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
33#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
34#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
35#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
George Karpenkovefef49c2018-08-21 03:09:02 +000036#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
George Karpenkov70c2ee32018-08-17 21:41:07 +000037#include "llvm/ADT/DenseMap.h"
38#include "llvm/ADT/FoldingSet.h"
39#include "llvm/ADT/ImmutableList.h"
40#include "llvm/ADT/ImmutableMap.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/SmallString.h"
43#include "llvm/ADT/StringExtras.h"
44#include <cstdarg>
45#include <utility>
46
George Karpenkov70c2ee32018-08-17 21:41:07 +000047namespace clang {
48namespace ento {
49namespace retaincountchecker {
50
51/// Metadata on reference.
52class RefVal {
53public:
54 enum Kind {
55 Owned = 0, // Owning reference.
56 NotOwned, // Reference is not owned by still valid (not freed).
57 Released, // Object has been released.
58 ReturnedOwned, // Returned object passes ownership to caller.
59 ReturnedNotOwned, // Return object does not pass ownership to caller.
60 ERROR_START,
61 ErrorDeallocNotOwned, // -dealloc called on non-owned object.
62 ErrorUseAfterRelease, // Object used after released.
63 ErrorReleaseNotOwned, // Release of an object that was not owned.
64 ERROR_LEAK_START,
65 ErrorLeak, // A memory leak due to excessive reference counts.
66 ErrorLeakReturned, // A memory leak due to the returning method not having
67 // the correct naming conventions.
68 ErrorOverAutorelease,
69 ErrorReturnedNotOwned
70 };
71
72 /// Tracks how an object referenced by an ivar has been used.
73 ///
74 /// This accounts for us not knowing if an arbitrary ivar is supposed to be
75 /// stored at +0 or +1.
76 enum class IvarAccessHistory {
77 None,
78 AccessedDirectly,
79 ReleasedAfterDirectAccess
80 };
81
82private:
83 /// The number of outstanding retains.
84 unsigned Cnt;
85 /// The number of outstanding autoreleases.
86 unsigned ACnt;
87 /// The (static) type of the object at the time we started tracking it.
88 QualType T;
89
90 /// The current state of the object.
91 ///
92 /// See the RefVal::Kind enum for possible values.
93 unsigned RawKind : 5;
94
95 /// The kind of object being tracked (CF or ObjC), if known.
96 ///
97 /// See the RetEffect::ObjKind enum for possible values.
George Karpenkovab0011e2018-08-23 00:26:59 +000098 unsigned RawObjectKind : 3;
George Karpenkov70c2ee32018-08-17 21:41:07 +000099
100 /// True if the current state and/or retain count may turn out to not be the
101 /// best possible approximation of the reference counting state.
102 ///
103 /// If true, the checker may decide to throw away ("override") this state
104 /// in favor of something else when it sees the object being used in new ways.
105 ///
106 /// This setting should not be propagated to state derived from this state.
107 /// Once we start deriving new states, it would be inconsistent to override
108 /// them.
109 unsigned RawIvarAccessHistory : 2;
110
111 RefVal(Kind k, RetEffect::ObjKind o, unsigned cnt, unsigned acnt, QualType t,
112 IvarAccessHistory IvarAccess)
113 : Cnt(cnt), ACnt(acnt), T(t), RawKind(static_cast<unsigned>(k)),
114 RawObjectKind(static_cast<unsigned>(o)),
115 RawIvarAccessHistory(static_cast<unsigned>(IvarAccess)) {
116 assert(getKind() == k && "not enough bits for the kind");
117 assert(getObjKind() == o && "not enough bits for the object kind");
118 assert(getIvarAccessHistory() == IvarAccess && "not enough bits");
119 }
120
121public:
122 Kind getKind() const { return static_cast<Kind>(RawKind); }
123
124 RetEffect::ObjKind getObjKind() const {
125 return static_cast<RetEffect::ObjKind>(RawObjectKind);
126 }
127
128 unsigned getCount() const { return Cnt; }
129 unsigned getAutoreleaseCount() const { return ACnt; }
130 unsigned getCombinedCounts() const { return Cnt + ACnt; }
131 void clearCounts() {
132 Cnt = 0;
133 ACnt = 0;
134 }
135 void setCount(unsigned i) {
136 Cnt = i;
137 }
138 void setAutoreleaseCount(unsigned i) {
139 ACnt = i;
140 }
141
142 QualType getType() const { return T; }
143
144 /// Returns what the analyzer knows about direct accesses to a particular
145 /// instance variable.
146 ///
147 /// If the object with this refcount wasn't originally from an Objective-C
148 /// ivar region, this should always return IvarAccessHistory::None.
149 IvarAccessHistory getIvarAccessHistory() const {
150 return static_cast<IvarAccessHistory>(RawIvarAccessHistory);
151 }
152
153 bool isOwned() const {
154 return getKind() == Owned;
155 }
156
157 bool isNotOwned() const {
158 return getKind() == NotOwned;
159 }
160
161 bool isReturnedOwned() const {
162 return getKind() == ReturnedOwned;
163 }
164
165 bool isReturnedNotOwned() const {
166 return getKind() == ReturnedNotOwned;
167 }
168
169 /// Create a state for an object whose lifetime is the responsibility of the
170 /// current function, at least partially.
171 ///
172 /// Most commonly, this is an owned object with a retain count of +1.
173 static RefVal makeOwned(RetEffect::ObjKind o, QualType t) {
174 return RefVal(Owned, o, /*Count=*/1, 0, t, IvarAccessHistory::None);
175 }
176
177 /// Create a state for an object whose lifetime is not the responsibility of
178 /// the current function.
179 ///
180 /// Most commonly, this is an unowned object with a retain count of +0.
181 static RefVal makeNotOwned(RetEffect::ObjKind o, QualType t) {
182 return RefVal(NotOwned, o, /*Count=*/0, 0, t, IvarAccessHistory::None);
183 }
184
185 RefVal operator-(size_t i) const {
186 return RefVal(getKind(), getObjKind(), getCount() - i,
187 getAutoreleaseCount(), getType(), getIvarAccessHistory());
188 }
189
190 RefVal operator+(size_t i) const {
191 return RefVal(getKind(), getObjKind(), getCount() + i,
192 getAutoreleaseCount(), getType(), getIvarAccessHistory());
193 }
194
195 RefVal operator^(Kind k) const {
196 return RefVal(k, getObjKind(), getCount(), getAutoreleaseCount(),
197 getType(), getIvarAccessHistory());
198 }
199
200 RefVal autorelease() const {
201 return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount()+1,
202 getType(), getIvarAccessHistory());
203 }
204
205 RefVal withIvarAccess() const {
206 assert(getIvarAccessHistory() == IvarAccessHistory::None);
207 return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount(),
208 getType(), IvarAccessHistory::AccessedDirectly);
209 }
210
211 RefVal releaseViaIvar() const {
212 assert(getIvarAccessHistory() == IvarAccessHistory::AccessedDirectly);
213 return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount(),
214 getType(), IvarAccessHistory::ReleasedAfterDirectAccess);
215 }
216
217 // Comparison, profiling, and pretty-printing.
George Karpenkov70c2ee32018-08-17 21:41:07 +0000218 bool hasSameState(const RefVal &X) const {
219 return getKind() == X.getKind() && Cnt == X.Cnt && ACnt == X.ACnt &&
220 getIvarAccessHistory() == X.getIvarAccessHistory();
221 }
222
223 bool operator==(const RefVal& X) const {
224 return T == X.T && hasSameState(X) && getObjKind() == X.getObjKind();
225 }
226
227 void Profile(llvm::FoldingSetNodeID& ID) const {
228 ID.Add(T);
229 ID.AddInteger(RawKind);
230 ID.AddInteger(Cnt);
231 ID.AddInteger(ACnt);
232 ID.AddInteger(RawObjectKind);
233 ID.AddInteger(RawIvarAccessHistory);
234 }
235
236 void print(raw_ostream &Out) const;
237};
238
239class RetainCountChecker
240 : public Checker< check::Bind,
241 check::DeadSymbols,
242 check::EndAnalysis,
243 check::BeginFunction,
244 check::EndFunction,
245 check::PostStmt<BlockExpr>,
246 check::PostStmt<CastExpr>,
247 check::PostStmt<ObjCArrayLiteral>,
248 check::PostStmt<ObjCDictionaryLiteral>,
249 check::PostStmt<ObjCBoxedExpr>,
250 check::PostStmt<ObjCIvarRefExpr>,
251 check::PostCall,
George Karpenkov70c2ee32018-08-17 21:41:07 +0000252 check::RegionChanges,
253 eval::Assume,
254 eval::Call > {
255 mutable std::unique_ptr<CFRefBug> useAfterRelease, releaseNotOwned;
256 mutable std::unique_ptr<CFRefBug> deallocNotOwned;
257 mutable std::unique_ptr<CFRefBug> overAutorelease, returnNotOwnedForOwned;
258 mutable std::unique_ptr<CFRefBug> leakWithinFunction, leakAtReturn;
259
260 typedef llvm::DenseMap<SymbolRef, const CheckerProgramPointTag *> SymbolTagMap;
261
262 // This map is only used to ensure proper deletion of any allocated tags.
263 mutable SymbolTagMap DeadSymbolTags;
264
265 mutable std::unique_ptr<RetainSummaryManager> Summaries;
266 mutable SummaryLogTy SummaryLog;
George Karpenkovab0011e2018-08-23 00:26:59 +0000267
George Karpenkov70c2ee32018-08-17 21:41:07 +0000268 mutable bool ShouldResetSummaryLog;
269
Kristof Umannc83b0dd2018-11-02 15:48:10 +0000270public:
George Karpenkov70c2ee32018-08-17 21:41:07 +0000271 /// Optional setting to indicate if leak reports should include
272 /// the allocation line.
Kristof Umannc83b0dd2018-11-02 15:48:10 +0000273 bool IncludeAllocationLine;
274 bool ShouldCheckOSObjectRetainCount;
George Karpenkov70c2ee32018-08-17 21:41:07 +0000275
Kristof Umannc83b0dd2018-11-02 15:48:10 +0000276 RetainCountChecker() : ShouldResetSummaryLog(false) {}
George Karpenkov70c2ee32018-08-17 21:41:07 +0000277
278 ~RetainCountChecker() override { DeleteContainerSeconds(DeadSymbolTags); }
279
280 void checkEndAnalysis(ExplodedGraph &G, BugReporter &BR,
281 ExprEngine &Eng) const {
282 // FIXME: This is a hack to make sure the summary log gets cleared between
283 // analyses of different code bodies.
284 //
285 // Why is this necessary? Because a checker's lifetime is tied to a
286 // translation unit, but an ExplodedGraph's lifetime is just a code body.
287 // Once in a blue moon, a new ExplodedNode will have the same address as an
288 // old one with an associated summary, and the bug report visitor gets very
289 // confused. (To make things worse, the summary lifetime is currently also
290 // tied to a code body, so we get a crash instead of incorrect results.)
291 //
292 // Why is this a bad solution? Because if the lifetime of the ExplodedGraph
293 // changes, things will start going wrong again. Really the lifetime of this
294 // log needs to be tied to either the specific nodes in it or the entire
295 // ExplodedGraph, not to a specific part of the code being analyzed.
296 //
297 // (Also, having stateful local data means that the same checker can't be
298 // used from multiple threads, but a lot of checkers have incorrect
299 // assumptions about that anyway. So that wasn't a priority at the time of
300 // this fix.)
301 //
302 // This happens at the end of analysis, but bug reports are emitted /after/
303 // this point. So we can't just clear the summary log now. Instead, we mark
304 // that the next time we access the summary log, it should be cleared.
305
306 // If we never reset the summary log during /this/ code body analysis,
307 // there were no new summaries. There might still have been summaries from
308 // the /last/ analysis, so clear them out to make sure the bug report
309 // visitors don't get confused.
310 if (ShouldResetSummaryLog)
311 SummaryLog.clear();
312
313 ShouldResetSummaryLog = !SummaryLog.empty();
314 }
315
316 CFRefBug *getLeakWithinFunctionBug(const LangOptions &LOpts) const {
317 if (!leakWithinFunction)
318 leakWithinFunction.reset(new Leak(this, "Leak"));
319 return leakWithinFunction.get();
320 }
321
322 CFRefBug *getLeakAtReturnBug(const LangOptions &LOpts) const {
323 if (!leakAtReturn)
324 leakAtReturn.reset(new Leak(this, "Leak of returned object"));
325 return leakAtReturn.get();
326 }
327
328 RetainSummaryManager &getSummaryManager(ASTContext &Ctx) const {
329 // FIXME: We don't support ARC being turned on and off during one analysis.
330 // (nor, for that matter, do we support changing ASTContexts)
331 bool ARCEnabled = (bool)Ctx.getLangOpts().ObjCAutoRefCount;
George Karpenkovab0011e2018-08-23 00:26:59 +0000332 if (!Summaries) {
333 Summaries.reset(new RetainSummaryManager(
Kristof Umannc83b0dd2018-11-02 15:48:10 +0000334 Ctx, ARCEnabled, ShouldCheckOSObjectRetainCount));
George Karpenkovab0011e2018-08-23 00:26:59 +0000335 } else {
George Karpenkov70c2ee32018-08-17 21:41:07 +0000336 assert(Summaries->isARCEnabled() == ARCEnabled);
George Karpenkovab0011e2018-08-23 00:26:59 +0000337 }
George Karpenkov70c2ee32018-08-17 21:41:07 +0000338 return *Summaries;
339 }
340
341 RetainSummaryManager &getSummaryManager(CheckerContext &C) const {
342 return getSummaryManager(C.getASTContext());
343 }
344
345 void printState(raw_ostream &Out, ProgramStateRef State,
346 const char *NL, const char *Sep) const override;
347
348 void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const;
349 void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
350 void checkPostStmt(const CastExpr *CE, CheckerContext &C) const;
351
352 void checkPostStmt(const ObjCArrayLiteral *AL, CheckerContext &C) const;
353 void checkPostStmt(const ObjCDictionaryLiteral *DL, CheckerContext &C) const;
354 void checkPostStmt(const ObjCBoxedExpr *BE, CheckerContext &C) const;
355
356 void checkPostStmt(const ObjCIvarRefExpr *IRE, CheckerContext &C) const;
357
358 void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
359
360 void checkSummary(const RetainSummary &Summ, const CallEvent &Call,
361 CheckerContext &C) const;
362
363 void processSummaryOfInlined(const RetainSummary &Summ,
364 const CallEvent &Call,
365 CheckerContext &C) const;
366
367 bool evalCall(const CallExpr *CE, CheckerContext &C) const;
368
369 ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
370 bool Assumption) const;
371
372 ProgramStateRef
373 checkRegionChanges(ProgramStateRef state,
374 const InvalidatedSymbols *invalidated,
375 ArrayRef<const MemRegion *> ExplicitRegions,
376 ArrayRef<const MemRegion *> Regions,
377 const LocationContext* LCtx,
378 const CallEvent *Call) const;
379
George Karpenkov04553e52018-09-21 20:37:20 +0000380 ExplodedNode* checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C,
George Karpenkov70c2ee32018-08-17 21:41:07 +0000381 ExplodedNode *Pred, RetEffect RE, RefVal X,
382 SymbolRef Sym, ProgramStateRef state) const;
383
384 void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
385 void checkBeginFunction(CheckerContext &C) const;
386 void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const;
387
388 ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym,
389 RefVal V, ArgEffect E, RefVal::Kind &hasErr,
390 CheckerContext &C) const;
391
392 void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange,
393 RefVal::Kind ErrorKind, SymbolRef Sym,
394 CheckerContext &C) const;
395
396 void processObjCLiterals(CheckerContext &C, const Expr *Ex) const;
397
398 const ProgramPointTag *getDeadSymbolTag(SymbolRef sym) const;
399
400 ProgramStateRef handleSymbolDeath(ProgramStateRef state,
401 SymbolRef sid, RefVal V,
402 SmallVectorImpl<SymbolRef> &Leaked) const;
403
404 ProgramStateRef
405 handleAutoreleaseCounts(ProgramStateRef state, ExplodedNode *Pred,
406 const ProgramPointTag *Tag, CheckerContext &Ctx,
George Karpenkov04553e52018-09-21 20:37:20 +0000407 SymbolRef Sym,
408 RefVal V,
409 const ReturnStmt *S=nullptr) const;
George Karpenkov70c2ee32018-08-17 21:41:07 +0000410
411 ExplodedNode *processLeaks(ProgramStateRef state,
412 SmallVectorImpl<SymbolRef> &Leaked,
413 CheckerContext &Ctx,
414 ExplodedNode *Pred = nullptr) const;
George Karpenkov04553e52018-09-21 20:37:20 +0000415
416private:
417 /// Perform the necessary checks and state adjustments at the end of the
418 /// function.
419 /// \p S Return statement, may be null.
420 ExplodedNode * processReturn(const ReturnStmt *S, CheckerContext &C) const;
George Karpenkov70c2ee32018-08-17 21:41:07 +0000421};
422
423//===----------------------------------------------------------------------===//
424// RefBindings - State used to track object reference counts.
425//===----------------------------------------------------------------------===//
426
427const RefVal *getRefBinding(ProgramStateRef State, SymbolRef Sym);
428
429ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym,
430 RefVal Val);
431
432ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym);
433
434/// Returns true if this stack frame is for an Objective-C method that is a
435/// property getter or setter whose body has been synthesized by the analyzer.
436inline bool isSynthesizedAccessor(const StackFrameContext *SFC) {
437 auto Method = dyn_cast_or_null<ObjCMethodDecl>(SFC->getDecl());
438 if (!Method || !Method->isPropertyAccessor())
439 return false;
440
441 return SFC->getAnalysisDeclContext()->isBodyAutosynthesized();
442}
443
444} // end namespace retaincountchecker
445} // end namespace ento
446} // end namespace clang
447
448#endif