RetainCountChecker.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. //==--- RetainCountChecker.h - Checks for leaks and other issues -*- C++ -*--//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines the methods for RetainCountChecker, which implements
  10. // a reference count checker for Core Foundation and Cocoa on (Mac OS X).
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_H
  14. #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_H
  15. #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
  16. #include "RetainCountDiagnostics.h"
  17. #include "clang/AST/Attr.h"
  18. #include "clang/AST/DeclCXX.h"
  19. #include "clang/AST/DeclObjC.h"
  20. #include "clang/AST/ParentMap.h"
  21. #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
  22. #include "clang/Analysis/PathDiagnostic.h"
  23. #include "clang/Analysis/RetainSummaryManager.h"
  24. #include "clang/Basic/LangOptions.h"
  25. #include "clang/Basic/SourceManager.h"
  26. #include "clang/Analysis/SelectorExtras.h"
  27. #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
  28. #include "clang/StaticAnalyzer/Core/Checker.h"
  29. #include "clang/StaticAnalyzer/Core/CheckerManager.h"
  30. #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
  31. #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
  32. #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
  33. #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
  34. #include "llvm/ADT/DenseMap.h"
  35. #include "llvm/ADT/FoldingSet.h"
  36. #include "llvm/ADT/ImmutableList.h"
  37. #include "llvm/ADT/ImmutableMap.h"
  38. #include "llvm/ADT/STLExtras.h"
  39. #include "llvm/ADT/SmallString.h"
  40. #include "llvm/ADT/StringExtras.h"
  41. #include <cstdarg>
  42. #include <utility>
  43. namespace clang {
  44. namespace ento {
  45. namespace retaincountchecker {
  46. /// Metadata on reference.
  47. class RefVal {
  48. public:
  49. enum Kind {
  50. Owned = 0, // Owning reference.
  51. NotOwned, // Reference is not owned by still valid (not freed).
  52. Released, // Object has been released.
  53. ReturnedOwned, // Returned object passes ownership to caller.
  54. ReturnedNotOwned, // Return object does not pass ownership to caller.
  55. ERROR_START,
  56. ErrorDeallocNotOwned, // -dealloc called on non-owned object.
  57. ErrorUseAfterRelease, // Object used after released.
  58. ErrorReleaseNotOwned, // Release of an object that was not owned.
  59. ERROR_LEAK_START,
  60. ErrorLeak, // A memory leak due to excessive reference counts.
  61. ErrorLeakReturned, // A memory leak due to the returning method not having
  62. // the correct naming conventions.
  63. ErrorOverAutorelease,
  64. ErrorReturnedNotOwned
  65. };
  66. /// Tracks how an object referenced by an ivar has been used.
  67. ///
  68. /// This accounts for us not knowing if an arbitrary ivar is supposed to be
  69. /// stored at +0 or +1.
  70. enum class IvarAccessHistory {
  71. None,
  72. AccessedDirectly,
  73. ReleasedAfterDirectAccess
  74. };
  75. private:
  76. /// The number of outstanding retains.
  77. unsigned Cnt;
  78. /// The number of outstanding autoreleases.
  79. unsigned ACnt;
  80. /// The (static) type of the object at the time we started tracking it.
  81. QualType T;
  82. /// The current state of the object.
  83. ///
  84. /// See the RefVal::Kind enum for possible values.
  85. unsigned RawKind : 5;
  86. /// The kind of object being tracked (CF or ObjC or OSObject), if known.
  87. ///
  88. /// See the ObjKind enum for possible values.
  89. unsigned RawObjectKind : 3;
  90. /// True if the current state and/or retain count may turn out to not be the
  91. /// best possible approximation of the reference counting state.
  92. ///
  93. /// If true, the checker may decide to throw away ("override") this state
  94. /// in favor of something else when it sees the object being used in new ways.
  95. ///
  96. /// This setting should not be propagated to state derived from this state.
  97. /// Once we start deriving new states, it would be inconsistent to override
  98. /// them.
  99. unsigned RawIvarAccessHistory : 2;
  100. RefVal(Kind k, ObjKind o, unsigned cnt, unsigned acnt, QualType t,
  101. IvarAccessHistory IvarAccess)
  102. : Cnt(cnt), ACnt(acnt), T(t), RawKind(static_cast<unsigned>(k)),
  103. RawObjectKind(static_cast<unsigned>(o)),
  104. RawIvarAccessHistory(static_cast<unsigned>(IvarAccess)) {
  105. assert(getKind() == k && "not enough bits for the kind");
  106. assert(getObjKind() == o && "not enough bits for the object kind");
  107. assert(getIvarAccessHistory() == IvarAccess && "not enough bits");
  108. }
  109. public:
  110. Kind getKind() const { return static_cast<Kind>(RawKind); }
  111. ObjKind getObjKind() const {
  112. return static_cast<ObjKind>(RawObjectKind);
  113. }
  114. unsigned getCount() const { return Cnt; }
  115. unsigned getAutoreleaseCount() const { return ACnt; }
  116. unsigned getCombinedCounts() const { return Cnt + ACnt; }
  117. void clearCounts() {
  118. Cnt = 0;
  119. ACnt = 0;
  120. }
  121. void setCount(unsigned i) {
  122. Cnt = i;
  123. }
  124. void setAutoreleaseCount(unsigned i) {
  125. ACnt = i;
  126. }
  127. QualType getType() const { return T; }
  128. /// Returns what the analyzer knows about direct accesses to a particular
  129. /// instance variable.
  130. ///
  131. /// If the object with this refcount wasn't originally from an Objective-C
  132. /// ivar region, this should always return IvarAccessHistory::None.
  133. IvarAccessHistory getIvarAccessHistory() const {
  134. return static_cast<IvarAccessHistory>(RawIvarAccessHistory);
  135. }
  136. bool isOwned() const {
  137. return getKind() == Owned;
  138. }
  139. bool isNotOwned() const {
  140. return getKind() == NotOwned;
  141. }
  142. bool isReturnedOwned() const {
  143. return getKind() == ReturnedOwned;
  144. }
  145. bool isReturnedNotOwned() const {
  146. return getKind() == ReturnedNotOwned;
  147. }
  148. /// Create a state for an object whose lifetime is the responsibility of the
  149. /// current function, at least partially.
  150. ///
  151. /// Most commonly, this is an owned object with a retain count of +1.
  152. static RefVal makeOwned(ObjKind o, QualType t) {
  153. return RefVal(Owned, o, /*Count=*/1, 0, t, IvarAccessHistory::None);
  154. }
  155. /// Create a state for an object whose lifetime is not the responsibility of
  156. /// the current function.
  157. ///
  158. /// Most commonly, this is an unowned object with a retain count of +0.
  159. static RefVal makeNotOwned(ObjKind o, QualType t) {
  160. return RefVal(NotOwned, o, /*Count=*/0, 0, t, IvarAccessHistory::None);
  161. }
  162. RefVal operator-(size_t i) const {
  163. return RefVal(getKind(), getObjKind(), getCount() - i,
  164. getAutoreleaseCount(), getType(), getIvarAccessHistory());
  165. }
  166. RefVal operator+(size_t i) const {
  167. return RefVal(getKind(), getObjKind(), getCount() + i,
  168. getAutoreleaseCount(), getType(), getIvarAccessHistory());
  169. }
  170. RefVal operator^(Kind k) const {
  171. return RefVal(k, getObjKind(), getCount(), getAutoreleaseCount(),
  172. getType(), getIvarAccessHistory());
  173. }
  174. RefVal autorelease() const {
  175. return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount()+1,
  176. getType(), getIvarAccessHistory());
  177. }
  178. RefVal withIvarAccess() const {
  179. assert(getIvarAccessHistory() == IvarAccessHistory::None);
  180. return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount(),
  181. getType(), IvarAccessHistory::AccessedDirectly);
  182. }
  183. RefVal releaseViaIvar() const {
  184. assert(getIvarAccessHistory() == IvarAccessHistory::AccessedDirectly);
  185. return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount(),
  186. getType(), IvarAccessHistory::ReleasedAfterDirectAccess);
  187. }
  188. // Comparison, profiling, and pretty-printing.
  189. bool hasSameState(const RefVal &X) const {
  190. return getKind() == X.getKind() && Cnt == X.Cnt && ACnt == X.ACnt &&
  191. getIvarAccessHistory() == X.getIvarAccessHistory();
  192. }
  193. bool operator==(const RefVal& X) const {
  194. return T == X.T && hasSameState(X) && getObjKind() == X.getObjKind();
  195. }
  196. void Profile(llvm::FoldingSetNodeID& ID) const {
  197. ID.Add(T);
  198. ID.AddInteger(RawKind);
  199. ID.AddInteger(Cnt);
  200. ID.AddInteger(ACnt);
  201. ID.AddInteger(RawObjectKind);
  202. ID.AddInteger(RawIvarAccessHistory);
  203. }
  204. void print(raw_ostream &Out) const;
  205. };
  206. class RetainCountChecker
  207. : public Checker< check::Bind,
  208. check::DeadSymbols,
  209. check::BeginFunction,
  210. check::EndFunction,
  211. check::PostStmt<BlockExpr>,
  212. check::PostStmt<CastExpr>,
  213. check::PostStmt<ObjCArrayLiteral>,
  214. check::PostStmt<ObjCDictionaryLiteral>,
  215. check::PostStmt<ObjCBoxedExpr>,
  216. check::PostStmt<ObjCIvarRefExpr>,
  217. check::PostCall,
  218. check::RegionChanges,
  219. eval::Assume,
  220. eval::Call > {
  221. public:
  222. std::unique_ptr<RefCountBug> UseAfterRelease;
  223. std::unique_ptr<RefCountBug> ReleaseNotOwned;
  224. std::unique_ptr<RefCountBug> DeallocNotOwned;
  225. std::unique_ptr<RefCountBug> FreeNotOwned;
  226. std::unique_ptr<RefCountBug> OverAutorelease;
  227. std::unique_ptr<RefCountBug> ReturnNotOwnedForOwned;
  228. std::unique_ptr<RefCountBug> LeakWithinFunction;
  229. std::unique_ptr<RefCountBug> LeakAtReturn;
  230. mutable std::unique_ptr<RetainSummaryManager> Summaries;
  231. static std::unique_ptr<CheckerProgramPointTag> DeallocSentTag;
  232. static std::unique_ptr<CheckerProgramPointTag> CastFailTag;
  233. /// Track Objective-C and CoreFoundation objects.
  234. bool TrackObjCAndCFObjects = false;
  235. /// Track sublcasses of OSObject.
  236. bool TrackOSObjects = false;
  237. /// Track initial parameters (for the entry point) for NS/CF objects.
  238. bool TrackNSCFStartParam = false;
  239. RetainCountChecker() {};
  240. RetainSummaryManager &getSummaryManager(ASTContext &Ctx) const {
  241. if (!Summaries)
  242. Summaries.reset(
  243. new RetainSummaryManager(Ctx, TrackObjCAndCFObjects, TrackOSObjects));
  244. return *Summaries;
  245. }
  246. RetainSummaryManager &getSummaryManager(CheckerContext &C) const {
  247. return getSummaryManager(C.getASTContext());
  248. }
  249. void printState(raw_ostream &Out, ProgramStateRef State,
  250. const char *NL, const char *Sep) const override;
  251. void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const;
  252. void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
  253. void checkPostStmt(const CastExpr *CE, CheckerContext &C) const;
  254. void checkPostStmt(const ObjCArrayLiteral *AL, CheckerContext &C) const;
  255. void checkPostStmt(const ObjCDictionaryLiteral *DL, CheckerContext &C) const;
  256. void checkPostStmt(const ObjCBoxedExpr *BE, CheckerContext &C) const;
  257. void checkPostStmt(const ObjCIvarRefExpr *IRE, CheckerContext &C) const;
  258. void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
  259. void checkSummary(const RetainSummary &Summ, const CallEvent &Call,
  260. CheckerContext &C) const;
  261. void processSummaryOfInlined(const RetainSummary &Summ,
  262. const CallEvent &Call,
  263. CheckerContext &C) const;
  264. bool evalCall(const CallEvent &Call, CheckerContext &C) const;
  265. ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
  266. bool Assumption) const;
  267. ProgramStateRef
  268. checkRegionChanges(ProgramStateRef state,
  269. const InvalidatedSymbols *invalidated,
  270. ArrayRef<const MemRegion *> ExplicitRegions,
  271. ArrayRef<const MemRegion *> Regions,
  272. const LocationContext* LCtx,
  273. const CallEvent *Call) const;
  274. ExplodedNode* checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C,
  275. ExplodedNode *Pred, RetEffect RE, RefVal X,
  276. SymbolRef Sym, ProgramStateRef state) const;
  277. void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
  278. void checkBeginFunction(CheckerContext &C) const;
  279. void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const;
  280. ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym,
  281. RefVal V, ArgEffect E, RefVal::Kind &hasErr,
  282. CheckerContext &C) const;
  283. const RefCountBug &errorKindToBugKind(RefVal::Kind ErrorKind,
  284. SymbolRef Sym) const;
  285. void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange,
  286. RefVal::Kind ErrorKind, SymbolRef Sym,
  287. CheckerContext &C) const;
  288. void processObjCLiterals(CheckerContext &C, const Expr *Ex) const;
  289. ProgramStateRef handleSymbolDeath(ProgramStateRef state,
  290. SymbolRef sid, RefVal V,
  291. SmallVectorImpl<SymbolRef> &Leaked) const;
  292. ProgramStateRef
  293. handleAutoreleaseCounts(ProgramStateRef state, ExplodedNode *Pred,
  294. const ProgramPointTag *Tag, CheckerContext &Ctx,
  295. SymbolRef Sym,
  296. RefVal V,
  297. const ReturnStmt *S=nullptr) const;
  298. ExplodedNode *processLeaks(ProgramStateRef state,
  299. SmallVectorImpl<SymbolRef> &Leaked,
  300. CheckerContext &Ctx,
  301. ExplodedNode *Pred = nullptr) const;
  302. static const CheckerProgramPointTag &getDeallocSentTag() {
  303. return *DeallocSentTag;
  304. }
  305. static const CheckerProgramPointTag &getCastFailTag() { return *CastFailTag; }
  306. private:
  307. /// Perform the necessary checks and state adjustments at the end of the
  308. /// function.
  309. /// \p S Return statement, may be null.
  310. ExplodedNode * processReturn(const ReturnStmt *S, CheckerContext &C) const;
  311. };
  312. //===----------------------------------------------------------------------===//
  313. // RefBindings - State used to track object reference counts.
  314. //===----------------------------------------------------------------------===//
  315. const RefVal *getRefBinding(ProgramStateRef State, SymbolRef Sym);
  316. /// Returns true if this stack frame is for an Objective-C method that is a
  317. /// property getter or setter whose body has been synthesized by the analyzer.
  318. inline bool isSynthesizedAccessor(const StackFrameContext *SFC) {
  319. auto Method = dyn_cast_or_null<ObjCMethodDecl>(SFC->getDecl());
  320. if (!Method || !Method->isPropertyAccessor())
  321. return false;
  322. return SFC->getAnalysisDeclContext()->isBodyAutosynthesized();
  323. }
  324. } // end namespace retaincountchecker
  325. } // end namespace ento
  326. } // end namespace clang
  327. #endif