RetainSummaryManager.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //=== RetainSummaryManager.h - Summaries for reference counting ---*- C++ -*--//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines summaries implementation for retain counting, which
  15. // implements a reference count checker for Core Foundation and Cocoa
  16. // on (Mac OS X).
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_CLANG_ANALYSIS_RETAINSUMMARYMANAGER_H
  20. #define LLVM_CLANG_ANALYSIS_RETAINSUMMARYMANAGER_H
  21. #include "llvm/ADT/DenseMap.h"
  22. #include "llvm/ADT/FoldingSet.h"
  23. #include "llvm/ADT/ImmutableMap.h"
  24. #include "clang/AST/Attr.h"
  25. #include "clang/AST/DeclCXX.h"
  26. #include "clang/AST/DeclObjC.h"
  27. #include "clang/AST/ParentMap.h"
  28. #include "clang/Analysis/AnyCall.h"
  29. #include "clang/Analysis/SelectorExtras.h"
  30. #include "llvm/ADT/STLExtras.h"
  31. using namespace clang;
  32. namespace clang {
  33. namespace ento {
  34. /// Determines the object kind of a tracked object.
  35. enum class ObjKind {
  36. /// Indicates that the tracked object is a CF object.
  37. CF,
  38. /// Indicates that the tracked object is an Objective-C object.
  39. ObjC,
  40. /// Indicates that the tracked object could be a CF or Objective-C object.
  41. AnyObj,
  42. /// Indicates that the tracked object is a generalized object.
  43. Generalized,
  44. /// Indicates that the tracking object is a descendant of a
  45. /// referenced-counted OSObject, used in the Darwin kernel.
  46. OS
  47. };
  48. enum ArgEffectKind {
  49. /// There is no effect.
  50. DoNothing,
  51. /// The argument is treated as if an -autorelease message had been sent to
  52. /// the referenced object.
  53. Autorelease,
  54. /// The argument is treated as if the referenced object was deallocated.
  55. Dealloc,
  56. /// The argument has its reference count decreased by 1.
  57. DecRef,
  58. /// The argument has its reference count decreased by 1 to model
  59. /// a transferred bridge cast under ARC.
  60. DecRefBridgedTransferred,
  61. /// The argument has its reference count increased by 1.
  62. IncRef,
  63. /// The argument is a pointer to a retain-counted object; on exit, the new
  64. /// value of the pointer is a +0 value.
  65. UnretainedOutParameter,
  66. /// The argument is a pointer to a retain-counted object; on exit, the new
  67. /// value of the pointer is a +1 value.
  68. RetainedOutParameter,
  69. /// The argument is a pointer to a retain-counted object; on exit, the new
  70. /// value of the pointer is a +1 value iff the return code is zero.
  71. RetainedOutParameterOnZero,
  72. /// The argument is a pointer to a retain-counted object; on exit, the new
  73. /// value of the pointer is a +1 value iff the return code is non-zero.
  74. RetainedOutParameterOnNonZero,
  75. /// The argument is treated as potentially escaping, meaning that
  76. /// even when its reference count hits 0 it should be treated as still
  77. /// possibly being alive as someone else *may* be holding onto the object.
  78. MayEscape,
  79. /// All typestate tracking of the object ceases. This is usually employed
  80. /// when the effect of the call is completely unknown.
  81. StopTracking,
  82. /// All typestate tracking of the object ceases. Unlike StopTracking,
  83. /// this is also enforced when the method body is inlined.
  84. ///
  85. /// In some cases, we obtain a better summary for this checker
  86. /// by looking at the call site than by inlining the function.
  87. /// Signifies that we should stop tracking the symbol even if
  88. /// the function is inlined.
  89. StopTrackingHard,
  90. /// Performs the combined functionality of DecRef and StopTrackingHard.
  91. ///
  92. /// The models the effect that the called function decrements the reference
  93. /// count of the argument and all typestate tracking on that argument
  94. /// should cease.
  95. DecRefAndStopTrackingHard,
  96. };
  97. /// An ArgEffect summarizes the retain count behavior on an argument or receiver
  98. /// to a function or method.
  99. class ArgEffect {
  100. ArgEffectKind K;
  101. ObjKind O;
  102. public:
  103. explicit ArgEffect(ArgEffectKind K = DoNothing, ObjKind O = ObjKind::AnyObj)
  104. : K(K), O(O) {}
  105. ArgEffectKind getKind() const { return K; }
  106. ObjKind getObjKind() const { return O; }
  107. ArgEffect withKind(ArgEffectKind NewK) {
  108. return ArgEffect(NewK, O);
  109. }
  110. bool operator==(const ArgEffect &Other) const {
  111. return K == Other.K && O == Other.O;
  112. }
  113. };
  114. /// RetEffect summarizes a call's retain/release behavior with respect
  115. /// to its return value.
  116. class RetEffect {
  117. public:
  118. enum Kind {
  119. /// Indicates that no retain count information is tracked for
  120. /// the return value.
  121. NoRet,
  122. /// Indicates that the returned value is an owned (+1) symbol.
  123. OwnedSymbol,
  124. /// Indicates that the returned value is an object with retain count
  125. /// semantics but that it is not owned (+0). This is the default
  126. /// for getters, etc.
  127. NotOwnedSymbol,
  128. /// Indicates that the return value is an owned object when the
  129. /// receiver is also a tracked object.
  130. OwnedWhenTrackedReceiver,
  131. // Treat this function as returning a non-tracked symbol even if
  132. // the function has been inlined. This is used where the call
  133. // site summary is more precise than the summary indirectly produced
  134. // by inlining the function
  135. NoRetHard
  136. };
  137. private:
  138. Kind K;
  139. ObjKind O;
  140. RetEffect(Kind k, ObjKind o = ObjKind::AnyObj) : K(k), O(o) {}
  141. public:
  142. Kind getKind() const { return K; }
  143. ObjKind getObjKind() const { return O; }
  144. bool isOwned() const {
  145. return K == OwnedSymbol || K == OwnedWhenTrackedReceiver;
  146. }
  147. bool notOwned() const {
  148. return K == NotOwnedSymbol;
  149. }
  150. bool operator==(const RetEffect &Other) const {
  151. return K == Other.K && O == Other.O;
  152. }
  153. static RetEffect MakeOwnedWhenTrackedReceiver() {
  154. return RetEffect(OwnedWhenTrackedReceiver, ObjKind::ObjC);
  155. }
  156. static RetEffect MakeOwned(ObjKind o) {
  157. return RetEffect(OwnedSymbol, o);
  158. }
  159. static RetEffect MakeNotOwned(ObjKind o) {
  160. return RetEffect(NotOwnedSymbol, o);
  161. }
  162. static RetEffect MakeNoRet() {
  163. return RetEffect(NoRet);
  164. }
  165. static RetEffect MakeNoRetHard() {
  166. return RetEffect(NoRetHard);
  167. }
  168. };
  169. /// A key identifying a summary.
  170. class ObjCSummaryKey {
  171. IdentifierInfo* II;
  172. Selector S;
  173. public:
  174. ObjCSummaryKey(IdentifierInfo* ii, Selector s)
  175. : II(ii), S(s) {}
  176. ObjCSummaryKey(const ObjCInterfaceDecl *d, Selector s)
  177. : II(d ? d->getIdentifier() : nullptr), S(s) {}
  178. ObjCSummaryKey(Selector s)
  179. : II(nullptr), S(s) {}
  180. IdentifierInfo *getIdentifier() const { return II; }
  181. Selector getSelector() const { return S; }
  182. };
  183. } // end namespace ento
  184. } // end namespace clang
  185. using namespace ento;
  186. namespace llvm {
  187. //===----------------------------------------------------------------------===//
  188. // Adapters for FoldingSet.
  189. //===----------------------------------------------------------------------===//
  190. template <> struct FoldingSetTrait<ArgEffect> {
  191. static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) {
  192. ID.AddInteger((unsigned) X.getKind());
  193. ID.AddInteger((unsigned) X.getObjKind());
  194. }
  195. };
  196. template <> struct FoldingSetTrait<RetEffect> {
  197. static inline void Profile(const RetEffect &X, FoldingSetNodeID &ID) {
  198. ID.AddInteger((unsigned) X.getKind());
  199. ID.AddInteger((unsigned) X.getObjKind());
  200. }
  201. };
  202. template <> struct DenseMapInfo<ObjCSummaryKey> {
  203. static inline ObjCSummaryKey getEmptyKey() {
  204. return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getEmptyKey(),
  205. DenseMapInfo<Selector>::getEmptyKey());
  206. }
  207. static inline ObjCSummaryKey getTombstoneKey() {
  208. return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getTombstoneKey(),
  209. DenseMapInfo<Selector>::getTombstoneKey());
  210. }
  211. static unsigned getHashValue(const ObjCSummaryKey &V) {
  212. typedef std::pair<IdentifierInfo*, Selector> PairTy;
  213. return DenseMapInfo<PairTy>::getHashValue(PairTy(V.getIdentifier(),
  214. V.getSelector()));
  215. }
  216. static bool isEqual(const ObjCSummaryKey& LHS, const ObjCSummaryKey& RHS) {
  217. return LHS.getIdentifier() == RHS.getIdentifier() &&
  218. LHS.getSelector() == RHS.getSelector();
  219. }
  220. };
  221. } // end llvm namespace
  222. namespace clang {
  223. namespace ento {
  224. /// ArgEffects summarizes the effects of a function/method call on all of
  225. /// its arguments.
  226. typedef llvm::ImmutableMap<unsigned, ArgEffect> ArgEffects;
  227. /// Summary for a function with respect to ownership changes.
  228. class RetainSummary {
  229. /// Args - a map of (index, ArgEffect) pairs, where index
  230. /// specifies the argument (starting from 0). This can be sparsely
  231. /// populated; arguments with no entry in Args use 'DefaultArgEffect'.
  232. ArgEffects Args;
  233. /// DefaultArgEffect - The default ArgEffect to apply to arguments that
  234. /// do not have an entry in Args.
  235. ArgEffect DefaultArgEffect;
  236. /// Receiver - If this summary applies to an Objective-C message expression,
  237. /// this is the effect applied to the state of the receiver.
  238. ArgEffect Receiver;
  239. /// Effect on "this" pointer - applicable only to C++ method calls.
  240. ArgEffect This;
  241. /// Ret - The effect on the return value. Used to indicate if the
  242. /// function/method call returns a new tracked symbol.
  243. RetEffect Ret;
  244. public:
  245. RetainSummary(ArgEffects A,
  246. RetEffect R,
  247. ArgEffect defaultEff,
  248. ArgEffect ReceiverEff,
  249. ArgEffect ThisEff)
  250. : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff),
  251. This(ThisEff), Ret(R) {}
  252. /// getArg - Return the argument effect on the argument specified by
  253. /// idx (starting from 0).
  254. ArgEffect getArg(unsigned idx) const {
  255. if (const ArgEffect *AE = Args.lookup(idx))
  256. return *AE;
  257. return DefaultArgEffect;
  258. }
  259. void addArg(ArgEffects::Factory &af, unsigned idx, ArgEffect e) {
  260. Args = af.add(Args, idx, e);
  261. }
  262. /// setDefaultArgEffect - Set the default argument effect.
  263. void setDefaultArgEffect(ArgEffect E) {
  264. DefaultArgEffect = E;
  265. }
  266. /// getRetEffect - Returns the effect on the return value of the call.
  267. RetEffect getRetEffect() const { return Ret; }
  268. /// setRetEffect - Set the effect of the return value of the call.
  269. void setRetEffect(RetEffect E) { Ret = E; }
  270. /// Sets the effect on the receiver of the message.
  271. void setReceiverEffect(ArgEffect e) { Receiver = e; }
  272. /// getReceiverEffect - Returns the effect on the receiver of the call.
  273. /// This is only meaningful if the summary applies to an ObjCMessageExpr*.
  274. ArgEffect getReceiverEffect() const { return Receiver; }
  275. /// \return the effect on the "this" receiver of the method call.
  276. /// This is only meaningful if the summary applies to CXXMethodDecl*.
  277. ArgEffect getThisEffect() const { return This; }
  278. ArgEffect getDefaultEffect() const { return DefaultArgEffect; }
  279. /// Set the effect of the method on "this".
  280. void setThisEffect(ArgEffect e) { This = e; }
  281. bool isNoop() const {
  282. return Ret == RetEffect::MakeNoRet() && Receiver.getKind() == DoNothing
  283. && DefaultArgEffect.getKind() == MayEscape && This.getKind() == DoNothing
  284. && Args.isEmpty();
  285. }
  286. /// Test if two retain summaries are identical. Note that merely equivalent
  287. /// summaries are not necessarily identical (for example, if an explicit
  288. /// argument effect matches the default effect).
  289. bool operator==(const RetainSummary &Other) const {
  290. return Args == Other.Args && DefaultArgEffect == Other.DefaultArgEffect &&
  291. Receiver == Other.Receiver && This == Other.This && Ret == Other.Ret;
  292. }
  293. /// Profile this summary for inclusion in a FoldingSet.
  294. void Profile(llvm::FoldingSetNodeID& ID) const {
  295. ID.Add(Args);
  296. ID.Add(DefaultArgEffect);
  297. ID.Add(Receiver);
  298. ID.Add(This);
  299. ID.Add(Ret);
  300. }
  301. /// A retain summary is simple if it has no ArgEffects other than the default.
  302. bool isSimple() const {
  303. return Args.isEmpty();
  304. }
  305. ArgEffects getArgEffects() const { return Args; }
  306. private:
  307. ArgEffect getDefaultArgEffect() const { return DefaultArgEffect; }
  308. friend class RetainSummaryManager;
  309. };
  310. class ObjCSummaryCache {
  311. typedef llvm::DenseMap<ObjCSummaryKey, const RetainSummary *> MapTy;
  312. MapTy M;
  313. public:
  314. ObjCSummaryCache() {}
  315. const RetainSummary * find(const ObjCInterfaceDecl *D, Selector S) {
  316. // Do a lookup with the (D,S) pair. If we find a match return
  317. // the iterator.
  318. ObjCSummaryKey K(D, S);
  319. MapTy::iterator I = M.find(K);
  320. if (I != M.end())
  321. return I->second;
  322. if (!D)
  323. return nullptr;
  324. // Walk the super chain. If we find a hit with a parent, we'll end
  325. // up returning that summary. We actually allow that key (null,S), as
  326. // we cache summaries for the null ObjCInterfaceDecl* to allow us to
  327. // generate initial summaries without having to worry about NSObject
  328. // being declared.
  329. // FIXME: We may change this at some point.
  330. for (ObjCInterfaceDecl *C=D->getSuperClass() ;; C=C->getSuperClass()) {
  331. if ((I = M.find(ObjCSummaryKey(C, S))) != M.end())
  332. break;
  333. if (!C)
  334. return nullptr;
  335. }
  336. // Cache the summary with original key to make the next lookup faster
  337. // and return the iterator.
  338. const RetainSummary *Summ = I->second;
  339. M[K] = Summ;
  340. return Summ;
  341. }
  342. const RetainSummary *find(IdentifierInfo* II, Selector S) {
  343. // FIXME: Class method lookup. Right now we don't have a good way
  344. // of going between IdentifierInfo* and the class hierarchy.
  345. MapTy::iterator I = M.find(ObjCSummaryKey(II, S));
  346. if (I == M.end())
  347. I = M.find(ObjCSummaryKey(S));
  348. return I == M.end() ? nullptr : I->second;
  349. }
  350. const RetainSummary *& operator[](ObjCSummaryKey K) {
  351. return M[K];
  352. }
  353. const RetainSummary *& operator[](Selector S) {
  354. return M[ ObjCSummaryKey(S) ];
  355. }
  356. };
  357. class RetainSummaryTemplate;
  358. class RetainSummaryManager {
  359. typedef llvm::DenseMap<const FunctionDecl*, const RetainSummary *>
  360. FuncSummariesTy;
  361. typedef ObjCSummaryCache ObjCMethodSummariesTy;
  362. typedef llvm::FoldingSetNodeWrapper<RetainSummary> CachedSummaryNode;
  363. /// Ctx - The ASTContext object for the analyzed ASTs.
  364. ASTContext &Ctx;
  365. /// Records whether or not the analyzed code runs in ARC mode.
  366. const bool ARCEnabled;
  367. /// Track Objective-C and CoreFoundation objects.
  368. const bool TrackObjCAndCFObjects;
  369. /// Track sublcasses of OSObject.
  370. const bool TrackOSObjects;
  371. /// FuncSummaries - A map from FunctionDecls to summaries.
  372. FuncSummariesTy FuncSummaries;
  373. /// ObjCClassMethodSummaries - A map from selectors (for instance methods)
  374. /// to summaries.
  375. ObjCMethodSummariesTy ObjCClassMethodSummaries;
  376. /// ObjCMethodSummaries - A map from selectors to summaries.
  377. ObjCMethodSummariesTy ObjCMethodSummaries;
  378. /// BPAlloc - A BumpPtrAllocator used for allocating summaries, ArgEffects,
  379. /// and all other data used by the checker.
  380. llvm::BumpPtrAllocator BPAlloc;
  381. /// AF - A factory for ArgEffects objects.
  382. ArgEffects::Factory AF;
  383. /// ObjCAllocRetE - Default return effect for methods returning Objective-C
  384. /// objects.
  385. RetEffect ObjCAllocRetE;
  386. /// ObjCInitRetE - Default return effect for init methods returning
  387. /// Objective-C objects.
  388. RetEffect ObjCInitRetE;
  389. /// SimpleSummaries - Used for uniquing summaries that don't have special
  390. /// effects.
  391. llvm::FoldingSet<CachedSummaryNode> SimpleSummaries;
  392. /// Create an OS object at +1.
  393. const RetainSummary *getOSSummaryCreateRule(const FunctionDecl *FD);
  394. /// Get an OS object at +0.
  395. const RetainSummary *getOSSummaryGetRule(const FunctionDecl *FD);
  396. /// Increment the reference count on OS object.
  397. const RetainSummary *getOSSummaryRetainRule(const FunctionDecl *FD);
  398. /// Decrement the reference count on OS object.
  399. const RetainSummary *getOSSummaryReleaseRule(const FunctionDecl *FD);
  400. /// Free the OS object.
  401. const RetainSummary *getOSSummaryFreeRule(const FunctionDecl *FD);
  402. const RetainSummary *getUnarySummary(const FunctionType* FT,
  403. ArgEffectKind AE);
  404. const RetainSummary *getCFSummaryCreateRule(const FunctionDecl *FD);
  405. const RetainSummary *getCFSummaryGetRule(const FunctionDecl *FD);
  406. const RetainSummary *getCFCreateGetRuleSummary(const FunctionDecl *FD);
  407. const RetainSummary *getPersistentSummary(const RetainSummary &OldSumm);
  408. const RetainSummary *
  409. getPersistentSummary(RetEffect RetEff, ArgEffects ScratchArgs,
  410. ArgEffect ReceiverEff = ArgEffect(DoNothing),
  411. ArgEffect DefaultEff = ArgEffect(MayEscape),
  412. ArgEffect ThisEff = ArgEffect(DoNothing)) {
  413. RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff, ThisEff);
  414. return getPersistentSummary(Summ);
  415. }
  416. const RetainSummary *getDoNothingSummary() {
  417. return getPersistentSummary(RetEffect::MakeNoRet(),
  418. ArgEffects(AF.getEmptyMap()),
  419. ArgEffect(DoNothing), ArgEffect(DoNothing));
  420. }
  421. const RetainSummary *getDefaultSummary() {
  422. return getPersistentSummary(RetEffect::MakeNoRet(),
  423. ArgEffects(AF.getEmptyMap()),
  424. ArgEffect(DoNothing), ArgEffect(MayEscape));
  425. }
  426. const RetainSummary *getPersistentStopSummary() {
  427. return getPersistentSummary(
  428. RetEffect::MakeNoRet(), ArgEffects(AF.getEmptyMap()),
  429. ArgEffect(StopTracking), ArgEffect(StopTracking));
  430. }
  431. void InitializeClassMethodSummaries();
  432. void InitializeMethodSummaries();
  433. void addNSObjectClsMethSummary(Selector S, const RetainSummary *Summ) {
  434. ObjCClassMethodSummaries[S] = Summ;
  435. }
  436. void addNSObjectMethSummary(Selector S, const RetainSummary *Summ) {
  437. ObjCMethodSummaries[S] = Summ;
  438. }
  439. void addClassMethSummary(const char* Cls, const char* name,
  440. const RetainSummary *Summ, bool isNullary = true) {
  441. IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
  442. Selector S = isNullary ? GetNullarySelector(name, Ctx)
  443. : GetUnarySelector(name, Ctx);
  444. ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
  445. }
  446. void addInstMethSummary(const char* Cls, const char* nullaryName,
  447. const RetainSummary *Summ) {
  448. IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
  449. Selector S = GetNullarySelector(nullaryName, Ctx);
  450. ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
  451. }
  452. template <typename... Keywords>
  453. void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy &Summaries,
  454. const RetainSummary *Summ, Keywords *... Kws) {
  455. Selector S = getKeywordSelector(Ctx, Kws...);
  456. Summaries[ObjCSummaryKey(ClsII, S)] = Summ;
  457. }
  458. template <typename... Keywords>
  459. void addInstMethSummary(const char *Cls, const RetainSummary *Summ,
  460. Keywords *... Kws) {
  461. addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, Kws...);
  462. }
  463. template <typename... Keywords>
  464. void addClsMethSummary(const char *Cls, const RetainSummary *Summ,
  465. Keywords *... Kws) {
  466. addMethodSummary(&Ctx.Idents.get(Cls), ObjCClassMethodSummaries, Summ,
  467. Kws...);
  468. }
  469. template <typename... Keywords>
  470. void addClsMethSummary(IdentifierInfo *II, const RetainSummary *Summ,
  471. Keywords *... Kws) {
  472. addMethodSummary(II, ObjCClassMethodSummaries, Summ, Kws...);
  473. }
  474. const RetainSummary * generateSummary(const FunctionDecl *FD,
  475. bool &AllowAnnotations);
  476. /// Return a summary for OSObject, or nullptr if not found.
  477. const RetainSummary *getSummaryForOSObject(const FunctionDecl *FD,
  478. StringRef FName, QualType RetTy);
  479. /// Return a summary for Objective-C or CF object, or nullptr if not found.
  480. const RetainSummary *getSummaryForObjCOrCFObject(
  481. const FunctionDecl *FD,
  482. StringRef FName,
  483. QualType RetTy,
  484. const FunctionType *FT,
  485. bool &AllowAnnotations);
  486. /// Apply the annotation of @c pd in function @c FD
  487. /// to the resulting summary stored in out-parameter @c Template.
  488. /// \return whether an annotation was applied.
  489. bool applyParamAnnotationEffect(const ParmVarDecl *pd, unsigned parm_idx,
  490. const NamedDecl *FD,
  491. RetainSummaryTemplate &Template);
  492. public:
  493. RetainSummaryManager(ASTContext &ctx, bool trackObjCAndCFObjects,
  494. bool trackOSObjects)
  495. : Ctx(ctx), ARCEnabled((bool)Ctx.getLangOpts().ObjCAutoRefCount),
  496. TrackObjCAndCFObjects(trackObjCAndCFObjects),
  497. TrackOSObjects(trackOSObjects), AF(BPAlloc),
  498. ObjCAllocRetE(ARCEnabled ? RetEffect::MakeNotOwned(ObjKind::ObjC)
  499. : RetEffect::MakeOwned(ObjKind::ObjC)),
  500. ObjCInitRetE(ARCEnabled ? RetEffect::MakeNotOwned(ObjKind::ObjC)
  501. : RetEffect::MakeOwnedWhenTrackedReceiver()) {
  502. InitializeClassMethodSummaries();
  503. InitializeMethodSummaries();
  504. }
  505. enum class BehaviorSummary {
  506. // Function does not return.
  507. NoOp,
  508. // Function returns the first argument.
  509. Identity,
  510. // Function returns "this" argument.
  511. IdentityThis,
  512. // Function either returns zero, or the input parameter.
  513. IdentityOrZero
  514. };
  515. Optional<BehaviorSummary> canEval(const CallExpr *CE, const FunctionDecl *FD,
  516. bool &hasTrustedImplementationAnnotation);
  517. /// \return Whether the type corresponds to a known smart pointer
  518. /// implementation (that is, everything about it is inlineable).
  519. static bool isKnownSmartPointer(QualType QT);
  520. bool isTrustedReferenceCountImplementation(const Decl *FD);
  521. const RetainSummary *getSummary(AnyCall C,
  522. bool HasNonZeroCallbackArg=false,
  523. bool IsReceiverUnconsumedSelf=false,
  524. QualType ReceiverType={});
  525. RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
  526. private:
  527. /// getMethodSummary - This version of getMethodSummary is used to query
  528. /// the summary for the current method being analyzed.
  529. const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD);
  530. const RetainSummary *getFunctionSummary(const FunctionDecl *FD);
  531. const RetainSummary *getMethodSummary(Selector S, const ObjCInterfaceDecl *ID,
  532. const ObjCMethodDecl *MD,
  533. QualType RetTy,
  534. ObjCMethodSummariesTy &CachedSummaries);
  535. const RetainSummary *
  536. getInstanceMethodSummary(const ObjCMessageExpr *ME, QualType ReceiverType);
  537. const RetainSummary *getClassMethodSummary(const ObjCMessageExpr *ME);
  538. const RetainSummary *getStandardMethodSummary(const ObjCMethodDecl *MD,
  539. Selector S, QualType RetTy);
  540. /// Determine if there is a special return effect for this function or method.
  541. Optional<RetEffect> getRetEffectFromAnnotations(QualType RetTy,
  542. const Decl *D);
  543. void updateSummaryFromAnnotations(const RetainSummary *&Summ,
  544. const ObjCMethodDecl *MD);
  545. void updateSummaryFromAnnotations(const RetainSummary *&Summ,
  546. const FunctionDecl *FD);
  547. const RetainSummary *updateSummaryForNonZeroCallbackArg(const RetainSummary *S,
  548. AnyCall &C);
  549. /// Special case '[super init];' and '[self init];'
  550. ///
  551. /// Even though calling '[super init]' without assigning the result to self
  552. /// and checking if the parent returns 'nil' is a bad pattern, it is common.
  553. /// Additionally, our Self Init checker already warns about it. To avoid
  554. /// overwhelming the user with messages from both checkers, we model the case
  555. /// of '[super init]' in cases when it is not consumed by another expression
  556. /// as if the call preserves the value of 'self'; essentially, assuming it can
  557. /// never fail and return 'nil'.
  558. /// Note, we don't want to just stop tracking the value since we want the
  559. /// RetainCount checker to report leaks and use-after-free if SelfInit checker
  560. /// is turned off.
  561. void updateSummaryForReceiverUnconsumedSelf(const RetainSummary *&S);
  562. /// Set argument types for arguments which are not doing anything.
  563. void updateSummaryForArgumentTypes(const AnyCall &C, const RetainSummary *&RS);
  564. /// Determine whether a declaration @c D of correspondent type (return
  565. /// type for functions/methods) @c QT has any of the given attributes,
  566. /// provided they pass necessary validation checks AND tracking the given
  567. /// attribute is enabled.
  568. /// Returns the object kind corresponding to the present attribute, or None,
  569. /// if none of the specified attributes are present.
  570. /// Crashes if passed an attribute which is not explicitly handled.
  571. template <class T>
  572. Optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
  573. template <class T1, class T2, class... Others>
  574. Optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
  575. friend class RetainSummaryTemplate;
  576. };
  577. // Used to avoid allocating long-term (BPAlloc'd) memory for default retain
  578. // summaries. If a function or method looks like it has a default summary, but
  579. // it has annotations, the annotations are added to the stack-based template
  580. // and then copied into managed memory.
  581. class RetainSummaryTemplate {
  582. RetainSummaryManager &Manager;
  583. const RetainSummary *&RealSummary;
  584. RetainSummary ScratchSummary;
  585. bool Accessed;
  586. public:
  587. RetainSummaryTemplate(const RetainSummary *&real, RetainSummaryManager &mgr)
  588. : Manager(mgr), RealSummary(real), ScratchSummary(*real), Accessed(false) {}
  589. ~RetainSummaryTemplate() {
  590. if (Accessed)
  591. RealSummary = Manager.getPersistentSummary(ScratchSummary);
  592. }
  593. RetainSummary &operator*() {
  594. Accessed = true;
  595. return ScratchSummary;
  596. }
  597. RetainSummary *operator->() {
  598. Accessed = true;
  599. return &ScratchSummary;
  600. }
  601. };
  602. } // end namespace ento
  603. } // end namespace clang
  604. #endif
  605. #ifdef __GNUC__
  606. #pragma GCC diagnostic pop
  607. #endif