RetainSummaryManager.cpp 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297
  1. //== RetainSummaryManager.cpp - Summaries for reference counting --*- 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 summaries implementation for retain counting, which
  10. // implements a reference count checker for Core Foundation, Cocoa
  11. // and OSObject (on Mac OS X).
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
  15. #include "clang/Analysis/RetainSummaryManager.h"
  16. #include "clang/AST/Attr.h"
  17. #include "clang/AST/DeclCXX.h"
  18. #include "clang/AST/DeclObjC.h"
  19. #include "clang/AST/ParentMap.h"
  20. #include "clang/ASTMatchers/ASTMatchFinder.h"
  21. #include <optional>
  22. using namespace clang;
  23. using namespace ento;
  24. template <class T>
  25. constexpr static bool isOneOf() {
  26. return false;
  27. }
  28. /// Helper function to check whether the class is one of the
  29. /// rest of varargs.
  30. template <class T, class P, class... ToCompare>
  31. constexpr static bool isOneOf() {
  32. return std::is_same_v<T, P> || isOneOf<T, ToCompare...>();
  33. }
  34. namespace {
  35. /// Fake attribute class for RC* attributes.
  36. struct GeneralizedReturnsRetainedAttr {
  37. static bool classof(const Attr *A) {
  38. if (auto AA = dyn_cast<AnnotateAttr>(A))
  39. return AA->getAnnotation() == "rc_ownership_returns_retained";
  40. return false;
  41. }
  42. };
  43. struct GeneralizedReturnsNotRetainedAttr {
  44. static bool classof(const Attr *A) {
  45. if (auto AA = dyn_cast<AnnotateAttr>(A))
  46. return AA->getAnnotation() == "rc_ownership_returns_not_retained";
  47. return false;
  48. }
  49. };
  50. struct GeneralizedConsumedAttr {
  51. static bool classof(const Attr *A) {
  52. if (auto AA = dyn_cast<AnnotateAttr>(A))
  53. return AA->getAnnotation() == "rc_ownership_consumed";
  54. return false;
  55. }
  56. };
  57. }
  58. template <class T>
  59. std::optional<ObjKind> RetainSummaryManager::hasAnyEnabledAttrOf(const Decl *D,
  60. QualType QT) {
  61. ObjKind K;
  62. if (isOneOf<T, CFConsumedAttr, CFReturnsRetainedAttr,
  63. CFReturnsNotRetainedAttr>()) {
  64. if (!TrackObjCAndCFObjects)
  65. return std::nullopt;
  66. K = ObjKind::CF;
  67. } else if (isOneOf<T, NSConsumedAttr, NSConsumesSelfAttr,
  68. NSReturnsAutoreleasedAttr, NSReturnsRetainedAttr,
  69. NSReturnsNotRetainedAttr, NSConsumesSelfAttr>()) {
  70. if (!TrackObjCAndCFObjects)
  71. return std::nullopt;
  72. if (isOneOf<T, NSReturnsRetainedAttr, NSReturnsAutoreleasedAttr,
  73. NSReturnsNotRetainedAttr>() &&
  74. !cocoa::isCocoaObjectRef(QT))
  75. return std::nullopt;
  76. K = ObjKind::ObjC;
  77. } else if (isOneOf<T, OSConsumedAttr, OSConsumesThisAttr,
  78. OSReturnsNotRetainedAttr, OSReturnsRetainedAttr,
  79. OSReturnsRetainedOnZeroAttr,
  80. OSReturnsRetainedOnNonZeroAttr>()) {
  81. if (!TrackOSObjects)
  82. return std::nullopt;
  83. K = ObjKind::OS;
  84. } else if (isOneOf<T, GeneralizedReturnsNotRetainedAttr,
  85. GeneralizedReturnsRetainedAttr,
  86. GeneralizedConsumedAttr>()) {
  87. K = ObjKind::Generalized;
  88. } else {
  89. llvm_unreachable("Unexpected attribute");
  90. }
  91. if (D->hasAttr<T>())
  92. return K;
  93. return std::nullopt;
  94. }
  95. template <class T1, class T2, class... Others>
  96. std::optional<ObjKind> RetainSummaryManager::hasAnyEnabledAttrOf(const Decl *D,
  97. QualType QT) {
  98. if (auto Out = hasAnyEnabledAttrOf<T1>(D, QT))
  99. return Out;
  100. return hasAnyEnabledAttrOf<T2, Others...>(D, QT);
  101. }
  102. const RetainSummary *
  103. RetainSummaryManager::getPersistentSummary(const RetainSummary &OldSumm) {
  104. // Unique "simple" summaries -- those without ArgEffects.
  105. if (OldSumm.isSimple()) {
  106. ::llvm::FoldingSetNodeID ID;
  107. OldSumm.Profile(ID);
  108. void *Pos;
  109. CachedSummaryNode *N = SimpleSummaries.FindNodeOrInsertPos(ID, Pos);
  110. if (!N) {
  111. N = (CachedSummaryNode *) BPAlloc.Allocate<CachedSummaryNode>();
  112. new (N) CachedSummaryNode(OldSumm);
  113. SimpleSummaries.InsertNode(N, Pos);
  114. }
  115. return &N->getValue();
  116. }
  117. RetainSummary *Summ = (RetainSummary *) BPAlloc.Allocate<RetainSummary>();
  118. new (Summ) RetainSummary(OldSumm);
  119. return Summ;
  120. }
  121. static bool isSubclass(const Decl *D,
  122. StringRef ClassName) {
  123. using namespace ast_matchers;
  124. DeclarationMatcher SubclassM =
  125. cxxRecordDecl(isSameOrDerivedFrom(std::string(ClassName)));
  126. return !(match(SubclassM, *D, D->getASTContext()).empty());
  127. }
  128. static bool isExactClass(const Decl *D, StringRef ClassName) {
  129. using namespace ast_matchers;
  130. DeclarationMatcher sameClassM =
  131. cxxRecordDecl(hasName(std::string(ClassName)));
  132. return !(match(sameClassM, *D, D->getASTContext()).empty());
  133. }
  134. static bool isOSObjectSubclass(const Decl *D) {
  135. return D && isSubclass(D, "OSMetaClassBase") &&
  136. !isExactClass(D, "OSMetaClass");
  137. }
  138. static bool isOSObjectDynamicCast(StringRef S) { return S == "safeMetaCast"; }
  139. static bool isOSObjectRequiredCast(StringRef S) {
  140. return S == "requiredMetaCast";
  141. }
  142. static bool isOSObjectThisCast(StringRef S) {
  143. return S == "metaCast";
  144. }
  145. static bool isOSObjectPtr(QualType QT) {
  146. return isOSObjectSubclass(QT->getPointeeCXXRecordDecl());
  147. }
  148. static bool isISLObjectRef(QualType Ty) {
  149. return StringRef(Ty.getAsString()).startswith("isl_");
  150. }
  151. static bool isOSIteratorSubclass(const Decl *D) {
  152. return isSubclass(D, "OSIterator");
  153. }
  154. static bool hasRCAnnotation(const Decl *D, StringRef rcAnnotation) {
  155. for (const auto *Ann : D->specific_attrs<AnnotateAttr>()) {
  156. if (Ann->getAnnotation() == rcAnnotation)
  157. return true;
  158. }
  159. return false;
  160. }
  161. static bool isRetain(const FunctionDecl *FD, StringRef FName) {
  162. return FName.startswith_insensitive("retain") ||
  163. FName.endswith_insensitive("retain");
  164. }
  165. static bool isRelease(const FunctionDecl *FD, StringRef FName) {
  166. return FName.startswith_insensitive("release") ||
  167. FName.endswith_insensitive("release");
  168. }
  169. static bool isAutorelease(const FunctionDecl *FD, StringRef FName) {
  170. return FName.startswith_insensitive("autorelease") ||
  171. FName.endswith_insensitive("autorelease");
  172. }
  173. static bool isMakeCollectable(StringRef FName) {
  174. return FName.contains_insensitive("MakeCollectable");
  175. }
  176. /// A function is OSObject related if it is declared on a subclass
  177. /// of OSObject, or any of the parameters is a subclass of an OSObject.
  178. static bool isOSObjectRelated(const CXXMethodDecl *MD) {
  179. if (isOSObjectSubclass(MD->getParent()))
  180. return true;
  181. for (ParmVarDecl *Param : MD->parameters()) {
  182. QualType PT = Param->getType()->getPointeeType();
  183. if (!PT.isNull())
  184. if (CXXRecordDecl *RD = PT->getAsCXXRecordDecl())
  185. if (isOSObjectSubclass(RD))
  186. return true;
  187. }
  188. return false;
  189. }
  190. bool
  191. RetainSummaryManager::isKnownSmartPointer(QualType QT) {
  192. QT = QT.getCanonicalType();
  193. const auto *RD = QT->getAsCXXRecordDecl();
  194. if (!RD)
  195. return false;
  196. const IdentifierInfo *II = RD->getIdentifier();
  197. if (II && II->getName() == "smart_ptr")
  198. if (const auto *ND = dyn_cast<NamespaceDecl>(RD->getDeclContext()))
  199. if (ND->getNameAsString() == "os")
  200. return true;
  201. return false;
  202. }
  203. const RetainSummary *
  204. RetainSummaryManager::getSummaryForOSObject(const FunctionDecl *FD,
  205. StringRef FName, QualType RetTy) {
  206. assert(TrackOSObjects &&
  207. "Requesting a summary for an OSObject but OSObjects are not tracked");
  208. if (RetTy->isPointerType()) {
  209. const CXXRecordDecl *PD = RetTy->getPointeeType()->getAsCXXRecordDecl();
  210. if (PD && isOSObjectSubclass(PD)) {
  211. if (isOSObjectDynamicCast(FName) || isOSObjectRequiredCast(FName) ||
  212. isOSObjectThisCast(FName))
  213. return getDefaultSummary();
  214. // TODO: Add support for the slightly common *Matching(table) idiom.
  215. // Cf. IOService::nameMatching() etc. - these function have an unusual
  216. // contract of returning at +0 or +1 depending on their last argument.
  217. if (FName.endswith("Matching")) {
  218. return getPersistentStopSummary();
  219. }
  220. // All objects returned with functions *not* starting with 'get',
  221. // or iterators, are returned at +1.
  222. if ((!FName.startswith("get") && !FName.startswith("Get")) ||
  223. isOSIteratorSubclass(PD)) {
  224. return getOSSummaryCreateRule(FD);
  225. } else {
  226. return getOSSummaryGetRule(FD);
  227. }
  228. }
  229. }
  230. if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
  231. const CXXRecordDecl *Parent = MD->getParent();
  232. if (Parent && isOSObjectSubclass(Parent)) {
  233. if (FName == "release" || FName == "taggedRelease")
  234. return getOSSummaryReleaseRule(FD);
  235. if (FName == "retain" || FName == "taggedRetain")
  236. return getOSSummaryRetainRule(FD);
  237. if (FName == "free")
  238. return getOSSummaryFreeRule(FD);
  239. if (MD->getOverloadedOperator() == OO_New)
  240. return getOSSummaryCreateRule(MD);
  241. }
  242. }
  243. return nullptr;
  244. }
  245. const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
  246. const FunctionDecl *FD,
  247. StringRef FName,
  248. QualType RetTy,
  249. const FunctionType *FT,
  250. bool &AllowAnnotations) {
  251. ArgEffects ScratchArgs(AF.getEmptyMap());
  252. std::string RetTyName = RetTy.getAsString();
  253. if (FName == "pthread_create" || FName == "pthread_setspecific") {
  254. // Part of: <rdar://problem/7299394> and <rdar://problem/11282706>.
  255. // This will be addressed better with IPA.
  256. return getPersistentStopSummary();
  257. } else if(FName == "NSMakeCollectable") {
  258. // Handle: id NSMakeCollectable(CFTypeRef)
  259. AllowAnnotations = false;
  260. return RetTy->isObjCIdType() ? getUnarySummary(FT, DoNothing)
  261. : getPersistentStopSummary();
  262. } else if (FName == "CMBufferQueueDequeueAndRetain" ||
  263. FName == "CMBufferQueueDequeueIfDataReadyAndRetain") {
  264. // Part of: <rdar://problem/39390714>.
  265. return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF),
  266. ScratchArgs,
  267. ArgEffect(DoNothing),
  268. ArgEffect(DoNothing));
  269. } else if (FName == "CFPlugInInstanceCreate") {
  270. return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs);
  271. } else if (FName == "IORegistryEntrySearchCFProperty" ||
  272. (RetTyName == "CFMutableDictionaryRef" &&
  273. (FName == "IOBSDNameMatching" || FName == "IOServiceMatching" ||
  274. FName == "IOServiceNameMatching" ||
  275. FName == "IORegistryEntryIDMatching" ||
  276. FName == "IOOpenFirmwarePathMatching"))) {
  277. // Part of <rdar://problem/6961230>. (IOKit)
  278. // This should be addressed using a API table.
  279. return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF), ScratchArgs,
  280. ArgEffect(DoNothing), ArgEffect(DoNothing));
  281. } else if (FName == "IOServiceGetMatchingService" ||
  282. FName == "IOServiceGetMatchingServices") {
  283. // FIXES: <rdar://problem/6326900>
  284. // This should be addressed using a API table. This strcmp is also
  285. // a little gross, but there is no need to super optimize here.
  286. ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(DecRef, ObjKind::CF));
  287. return getPersistentSummary(RetEffect::MakeNoRet(),
  288. ScratchArgs,
  289. ArgEffect(DoNothing), ArgEffect(DoNothing));
  290. } else if (FName == "IOServiceAddNotification" ||
  291. FName == "IOServiceAddMatchingNotification") {
  292. // Part of <rdar://problem/6961230>. (IOKit)
  293. // This should be addressed using a API table.
  294. ScratchArgs = AF.add(ScratchArgs, 2, ArgEffect(DecRef, ObjKind::CF));
  295. return getPersistentSummary(RetEffect::MakeNoRet(),
  296. ScratchArgs,
  297. ArgEffect(DoNothing), ArgEffect(DoNothing));
  298. } else if (FName == "CVPixelBufferCreateWithBytes") {
  299. // FIXES: <rdar://problem/7283567>
  300. // Eventually this can be improved by recognizing that the pixel
  301. // buffer passed to CVPixelBufferCreateWithBytes is released via
  302. // a callback and doing full IPA to make sure this is done correctly.
  303. // FIXME: This function has an out parameter that returns an
  304. // allocated object.
  305. ScratchArgs = AF.add(ScratchArgs, 7, ArgEffect(StopTracking));
  306. return getPersistentSummary(RetEffect::MakeNoRet(),
  307. ScratchArgs,
  308. ArgEffect(DoNothing), ArgEffect(DoNothing));
  309. } else if (FName == "CGBitmapContextCreateWithData") {
  310. // FIXES: <rdar://problem/7358899>
  311. // Eventually this can be improved by recognizing that 'releaseInfo'
  312. // passed to CGBitmapContextCreateWithData is released via
  313. // a callback and doing full IPA to make sure this is done correctly.
  314. ScratchArgs = AF.add(ScratchArgs, 8, ArgEffect(ArgEffect(StopTracking)));
  315. return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF), ScratchArgs,
  316. ArgEffect(DoNothing), ArgEffect(DoNothing));
  317. } else if (FName == "CVPixelBufferCreateWithPlanarBytes") {
  318. // FIXES: <rdar://problem/7283567>
  319. // Eventually this can be improved by recognizing that the pixel
  320. // buffer passed to CVPixelBufferCreateWithPlanarBytes is released
  321. // via a callback and doing full IPA to make sure this is done
  322. // correctly.
  323. ScratchArgs = AF.add(ScratchArgs, 12, ArgEffect(StopTracking));
  324. return getPersistentSummary(RetEffect::MakeNoRet(),
  325. ScratchArgs,
  326. ArgEffect(DoNothing), ArgEffect(DoNothing));
  327. } else if (FName == "VTCompressionSessionEncodeFrame") {
  328. // The context argument passed to VTCompressionSessionEncodeFrame()
  329. // is passed to the callback specified when creating the session
  330. // (e.g. with VTCompressionSessionCreate()) which can release it.
  331. // To account for this possibility, conservatively stop tracking
  332. // the context.
  333. ScratchArgs = AF.add(ScratchArgs, 5, ArgEffect(StopTracking));
  334. return getPersistentSummary(RetEffect::MakeNoRet(),
  335. ScratchArgs,
  336. ArgEffect(DoNothing), ArgEffect(DoNothing));
  337. } else if (FName == "dispatch_set_context" ||
  338. FName == "xpc_connection_set_context") {
  339. // <rdar://problem/11059275> - The analyzer currently doesn't have
  340. // a good way to reason about the finalizer function for libdispatch.
  341. // If we pass a context object that is memory managed, stop tracking it.
  342. // <rdar://problem/13783514> - Same problem, but for XPC.
  343. // FIXME: this hack should possibly go away once we can handle
  344. // libdispatch and XPC finalizers.
  345. ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(StopTracking));
  346. return getPersistentSummary(RetEffect::MakeNoRet(),
  347. ScratchArgs,
  348. ArgEffect(DoNothing), ArgEffect(DoNothing));
  349. } else if (FName.startswith("NSLog")) {
  350. return getDoNothingSummary();
  351. } else if (FName.startswith("NS") && FName.contains("Insert")) {
  352. // Allowlist NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
  353. // be deallocated by NSMapRemove. (radar://11152419)
  354. ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(StopTracking));
  355. ScratchArgs = AF.add(ScratchArgs, 2, ArgEffect(StopTracking));
  356. return getPersistentSummary(RetEffect::MakeNoRet(),
  357. ScratchArgs, ArgEffect(DoNothing),
  358. ArgEffect(DoNothing));
  359. }
  360. if (RetTy->isPointerType()) {
  361. // For CoreFoundation ('CF') types.
  362. if (cocoa::isRefType(RetTy, "CF", FName)) {
  363. if (isRetain(FD, FName)) {
  364. // CFRetain isn't supposed to be annotated. However, this may as
  365. // well be a user-made "safe" CFRetain function that is incorrectly
  366. // annotated as cf_returns_retained due to lack of better options.
  367. // We want to ignore such annotation.
  368. AllowAnnotations = false;
  369. return getUnarySummary(FT, IncRef);
  370. } else if (isAutorelease(FD, FName)) {
  371. // The headers use cf_consumed, but we can fully model CFAutorelease
  372. // ourselves.
  373. AllowAnnotations = false;
  374. return getUnarySummary(FT, Autorelease);
  375. } else if (isMakeCollectable(FName)) {
  376. AllowAnnotations = false;
  377. return getUnarySummary(FT, DoNothing);
  378. } else {
  379. return getCFCreateGetRuleSummary(FD);
  380. }
  381. }
  382. // For CoreGraphics ('CG') and CoreVideo ('CV') types.
  383. if (cocoa::isRefType(RetTy, "CG", FName) ||
  384. cocoa::isRefType(RetTy, "CV", FName)) {
  385. if (isRetain(FD, FName))
  386. return getUnarySummary(FT, IncRef);
  387. else
  388. return getCFCreateGetRuleSummary(FD);
  389. }
  390. // For all other CF-style types, use the Create/Get
  391. // rule for summaries but don't support Retain functions
  392. // with framework-specific prefixes.
  393. if (coreFoundation::isCFObjectRef(RetTy)) {
  394. return getCFCreateGetRuleSummary(FD);
  395. }
  396. if (FD->hasAttr<CFAuditedTransferAttr>()) {
  397. return getCFCreateGetRuleSummary(FD);
  398. }
  399. }
  400. // Check for release functions, the only kind of functions that we care
  401. // about that don't return a pointer type.
  402. if (FName.startswith("CG") || FName.startswith("CF")) {
  403. // Test for 'CGCF'.
  404. FName = FName.substr(FName.startswith("CGCF") ? 4 : 2);
  405. if (isRelease(FD, FName))
  406. return getUnarySummary(FT, DecRef);
  407. else {
  408. assert(ScratchArgs.isEmpty());
  409. // Remaining CoreFoundation and CoreGraphics functions.
  410. // We use to assume that they all strictly followed the ownership idiom
  411. // and that ownership cannot be transferred. While this is technically
  412. // correct, many methods allow a tracked object to escape. For example:
  413. //
  414. // CFMutableDictionaryRef x = CFDictionaryCreateMutable(...);
  415. // CFDictionaryAddValue(y, key, x);
  416. // CFRelease(x);
  417. // ... it is okay to use 'x' since 'y' has a reference to it
  418. //
  419. // We handle this and similar cases with the follow heuristic. If the
  420. // function name contains "InsertValue", "SetValue", "AddValue",
  421. // "AppendValue", or "SetAttribute", then we assume that arguments may
  422. // "escape." This means that something else holds on to the object,
  423. // allowing it be used even after its local retain count drops to 0.
  424. ArgEffectKind E =
  425. (StrInStrNoCase(FName, "InsertValue") != StringRef::npos ||
  426. StrInStrNoCase(FName, "AddValue") != StringRef::npos ||
  427. StrInStrNoCase(FName, "SetValue") != StringRef::npos ||
  428. StrInStrNoCase(FName, "AppendValue") != StringRef::npos ||
  429. StrInStrNoCase(FName, "SetAttribute") != StringRef::npos)
  430. ? MayEscape
  431. : DoNothing;
  432. return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs,
  433. ArgEffect(DoNothing), ArgEffect(E, ObjKind::CF));
  434. }
  435. }
  436. return nullptr;
  437. }
  438. const RetainSummary *
  439. RetainSummaryManager::generateSummary(const FunctionDecl *FD,
  440. bool &AllowAnnotations) {
  441. // We generate "stop" summaries for implicitly defined functions.
  442. if (FD->isImplicit())
  443. return getPersistentStopSummary();
  444. const IdentifierInfo *II = FD->getIdentifier();
  445. StringRef FName = II ? II->getName() : "";
  446. // Strip away preceding '_'. Doing this here will effect all the checks
  447. // down below.
  448. FName = FName.substr(FName.find_first_not_of('_'));
  449. // Inspect the result type. Strip away any typedefs.
  450. const auto *FT = FD->getType()->castAs<FunctionType>();
  451. QualType RetTy = FT->getReturnType();
  452. if (TrackOSObjects)
  453. if (const RetainSummary *S = getSummaryForOSObject(FD, FName, RetTy))
  454. return S;
  455. if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
  456. if (!isOSObjectRelated(MD))
  457. return getPersistentSummary(RetEffect::MakeNoRet(),
  458. ArgEffects(AF.getEmptyMap()),
  459. ArgEffect(DoNothing),
  460. ArgEffect(StopTracking),
  461. ArgEffect(DoNothing));
  462. if (TrackObjCAndCFObjects)
  463. if (const RetainSummary *S =
  464. getSummaryForObjCOrCFObject(FD, FName, RetTy, FT, AllowAnnotations))
  465. return S;
  466. return getDefaultSummary();
  467. }
  468. const RetainSummary *
  469. RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) {
  470. // If we don't know what function we're calling, use our default summary.
  471. if (!FD)
  472. return getDefaultSummary();
  473. // Look up a summary in our cache of FunctionDecls -> Summaries.
  474. FuncSummariesTy::iterator I = FuncSummaries.find(FD);
  475. if (I != FuncSummaries.end())
  476. return I->second;
  477. // No summary? Generate one.
  478. bool AllowAnnotations = true;
  479. const RetainSummary *S = generateSummary(FD, AllowAnnotations);
  480. // Annotations override defaults.
  481. if (AllowAnnotations)
  482. updateSummaryFromAnnotations(S, FD);
  483. FuncSummaries[FD] = S;
  484. return S;
  485. }
  486. //===----------------------------------------------------------------------===//
  487. // Summary creation for functions (largely uses of Core Foundation).
  488. //===----------------------------------------------------------------------===//
  489. static ArgEffect getStopTrackingHardEquivalent(ArgEffect E) {
  490. switch (E.getKind()) {
  491. case DoNothing:
  492. case Autorelease:
  493. case DecRefBridgedTransferred:
  494. case IncRef:
  495. case UnretainedOutParameter:
  496. case RetainedOutParameter:
  497. case RetainedOutParameterOnZero:
  498. case RetainedOutParameterOnNonZero:
  499. case MayEscape:
  500. case StopTracking:
  501. case StopTrackingHard:
  502. return E.withKind(StopTrackingHard);
  503. case DecRef:
  504. case DecRefAndStopTrackingHard:
  505. return E.withKind(DecRefAndStopTrackingHard);
  506. case Dealloc:
  507. return E.withKind(Dealloc);
  508. }
  509. llvm_unreachable("Unknown ArgEffect kind");
  510. }
  511. const RetainSummary *
  512. RetainSummaryManager::updateSummaryForNonZeroCallbackArg(const RetainSummary *S,
  513. AnyCall &C) {
  514. ArgEffect RecEffect = getStopTrackingHardEquivalent(S->getReceiverEffect());
  515. ArgEffect DefEffect = getStopTrackingHardEquivalent(S->getDefaultArgEffect());
  516. ArgEffects ScratchArgs(AF.getEmptyMap());
  517. ArgEffects CustomArgEffects = S->getArgEffects();
  518. for (ArgEffects::iterator I = CustomArgEffects.begin(),
  519. E = CustomArgEffects.end();
  520. I != E; ++I) {
  521. ArgEffect Translated = getStopTrackingHardEquivalent(I->second);
  522. if (Translated.getKind() != DefEffect.getKind())
  523. ScratchArgs = AF.add(ScratchArgs, I->first, Translated);
  524. }
  525. RetEffect RE = RetEffect::MakeNoRetHard();
  526. // Special cases where the callback argument CANNOT free the return value.
  527. // This can generally only happen if we know that the callback will only be
  528. // called when the return value is already being deallocated.
  529. if (const IdentifierInfo *Name = C.getIdentifier()) {
  530. // When the CGBitmapContext is deallocated, the callback here will free
  531. // the associated data buffer.
  532. // The callback in dispatch_data_create frees the buffer, but not
  533. // the data object.
  534. if (Name->isStr("CGBitmapContextCreateWithData") ||
  535. Name->isStr("dispatch_data_create"))
  536. RE = S->getRetEffect();
  537. }
  538. return getPersistentSummary(RE, ScratchArgs, RecEffect, DefEffect);
  539. }
  540. void RetainSummaryManager::updateSummaryForReceiverUnconsumedSelf(
  541. const RetainSummary *&S) {
  542. RetainSummaryTemplate Template(S, *this);
  543. Template->setReceiverEffect(ArgEffect(DoNothing));
  544. Template->setRetEffect(RetEffect::MakeNoRet());
  545. }
  546. void RetainSummaryManager::updateSummaryForArgumentTypes(
  547. const AnyCall &C, const RetainSummary *&RS) {
  548. RetainSummaryTemplate Template(RS, *this);
  549. unsigned parm_idx = 0;
  550. for (auto pi = C.param_begin(), pe = C.param_end(); pi != pe;
  551. ++pi, ++parm_idx) {
  552. QualType QT = (*pi)->getType();
  553. // Skip already created values.
  554. if (RS->getArgEffects().contains(parm_idx))
  555. continue;
  556. ObjKind K = ObjKind::AnyObj;
  557. if (isISLObjectRef(QT)) {
  558. K = ObjKind::Generalized;
  559. } else if (isOSObjectPtr(QT)) {
  560. K = ObjKind::OS;
  561. } else if (cocoa::isCocoaObjectRef(QT)) {
  562. K = ObjKind::ObjC;
  563. } else if (coreFoundation::isCFObjectRef(QT)) {
  564. K = ObjKind::CF;
  565. }
  566. if (K != ObjKind::AnyObj)
  567. Template->addArg(AF, parm_idx,
  568. ArgEffect(RS->getDefaultArgEffect().getKind(), K));
  569. }
  570. }
  571. const RetainSummary *
  572. RetainSummaryManager::getSummary(AnyCall C,
  573. bool HasNonZeroCallbackArg,
  574. bool IsReceiverUnconsumedSelf,
  575. QualType ReceiverType) {
  576. const RetainSummary *Summ;
  577. switch (C.getKind()) {
  578. case AnyCall::Function:
  579. case AnyCall::Constructor:
  580. case AnyCall::InheritedConstructor:
  581. case AnyCall::Allocator:
  582. case AnyCall::Deallocator:
  583. Summ = getFunctionSummary(cast_or_null<FunctionDecl>(C.getDecl()));
  584. break;
  585. case AnyCall::Block:
  586. case AnyCall::Destructor:
  587. // FIXME: These calls are currently unsupported.
  588. return getPersistentStopSummary();
  589. case AnyCall::ObjCMethod: {
  590. const auto *ME = cast_or_null<ObjCMessageExpr>(C.getExpr());
  591. if (!ME) {
  592. Summ = getMethodSummary(cast<ObjCMethodDecl>(C.getDecl()));
  593. } else if (ME->isInstanceMessage()) {
  594. Summ = getInstanceMethodSummary(ME, ReceiverType);
  595. } else {
  596. Summ = getClassMethodSummary(ME);
  597. }
  598. break;
  599. }
  600. }
  601. if (HasNonZeroCallbackArg)
  602. Summ = updateSummaryForNonZeroCallbackArg(Summ, C);
  603. if (IsReceiverUnconsumedSelf)
  604. updateSummaryForReceiverUnconsumedSelf(Summ);
  605. updateSummaryForArgumentTypes(C, Summ);
  606. assert(Summ && "Unknown call type?");
  607. return Summ;
  608. }
  609. const RetainSummary *
  610. RetainSummaryManager::getCFCreateGetRuleSummary(const FunctionDecl *FD) {
  611. if (coreFoundation::followsCreateRule(FD))
  612. return getCFSummaryCreateRule(FD);
  613. return getCFSummaryGetRule(FD);
  614. }
  615. bool RetainSummaryManager::isTrustedReferenceCountImplementation(
  616. const Decl *FD) {
  617. return hasRCAnnotation(FD, "rc_ownership_trusted_implementation");
  618. }
  619. std::optional<RetainSummaryManager::BehaviorSummary>
  620. RetainSummaryManager::canEval(const CallExpr *CE, const FunctionDecl *FD,
  621. bool &hasTrustedImplementationAnnotation) {
  622. IdentifierInfo *II = FD->getIdentifier();
  623. if (!II)
  624. return std::nullopt;
  625. StringRef FName = II->getName();
  626. FName = FName.substr(FName.find_first_not_of('_'));
  627. QualType ResultTy = CE->getCallReturnType(Ctx);
  628. if (ResultTy->isObjCIdType()) {
  629. if (II->isStr("NSMakeCollectable"))
  630. return BehaviorSummary::Identity;
  631. } else if (ResultTy->isPointerType()) {
  632. // Handle: (CF|CG|CV)Retain
  633. // CFAutorelease
  634. // It's okay to be a little sloppy here.
  635. if (FName == "CMBufferQueueDequeueAndRetain" ||
  636. FName == "CMBufferQueueDequeueIfDataReadyAndRetain") {
  637. // Part of: <rdar://problem/39390714>.
  638. // These are not retain. They just return something and retain it.
  639. return std::nullopt;
  640. }
  641. if (CE->getNumArgs() == 1 &&
  642. (cocoa::isRefType(ResultTy, "CF", FName) ||
  643. cocoa::isRefType(ResultTy, "CG", FName) ||
  644. cocoa::isRefType(ResultTy, "CV", FName)) &&
  645. (isRetain(FD, FName) || isAutorelease(FD, FName) ||
  646. isMakeCollectable(FName)))
  647. return BehaviorSummary::Identity;
  648. // safeMetaCast is called by OSDynamicCast.
  649. // We assume that OSDynamicCast is either an identity (cast is OK,
  650. // the input was non-zero),
  651. // or that it returns zero (when the cast failed, or the input
  652. // was zero).
  653. if (TrackOSObjects) {
  654. if (isOSObjectDynamicCast(FName) && FD->param_size() >= 1) {
  655. return BehaviorSummary::IdentityOrZero;
  656. } else if (isOSObjectRequiredCast(FName) && FD->param_size() >= 1) {
  657. return BehaviorSummary::Identity;
  658. } else if (isOSObjectThisCast(FName) && isa<CXXMethodDecl>(FD) &&
  659. !cast<CXXMethodDecl>(FD)->isStatic()) {
  660. return BehaviorSummary::IdentityThis;
  661. }
  662. }
  663. const FunctionDecl* FDD = FD->getDefinition();
  664. if (FDD && isTrustedReferenceCountImplementation(FDD)) {
  665. hasTrustedImplementationAnnotation = true;
  666. return BehaviorSummary::Identity;
  667. }
  668. }
  669. if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
  670. const CXXRecordDecl *Parent = MD->getParent();
  671. if (TrackOSObjects && Parent && isOSObjectSubclass(Parent))
  672. if (FName == "release" || FName == "retain")
  673. return BehaviorSummary::NoOp;
  674. }
  675. return std::nullopt;
  676. }
  677. const RetainSummary *
  678. RetainSummaryManager::getUnarySummary(const FunctionType* FT,
  679. ArgEffectKind AE) {
  680. // Unary functions have no arg effects by definition.
  681. ArgEffects ScratchArgs(AF.getEmptyMap());
  682. // Verify that this is *really* a unary function. This can
  683. // happen if people do weird things.
  684. const FunctionProtoType* FTP = dyn_cast<FunctionProtoType>(FT);
  685. if (!FTP || FTP->getNumParams() != 1)
  686. return getPersistentStopSummary();
  687. ArgEffect Effect(AE, ObjKind::CF);
  688. ScratchArgs = AF.add(ScratchArgs, 0, Effect);
  689. return getPersistentSummary(RetEffect::MakeNoRet(),
  690. ScratchArgs,
  691. ArgEffect(DoNothing), ArgEffect(DoNothing));
  692. }
  693. const RetainSummary *
  694. RetainSummaryManager::getOSSummaryRetainRule(const FunctionDecl *FD) {
  695. return getPersistentSummary(RetEffect::MakeNoRet(),
  696. AF.getEmptyMap(),
  697. /*ReceiverEff=*/ArgEffect(DoNothing),
  698. /*DefaultEff=*/ArgEffect(DoNothing),
  699. /*ThisEff=*/ArgEffect(IncRef, ObjKind::OS));
  700. }
  701. const RetainSummary *
  702. RetainSummaryManager::getOSSummaryReleaseRule(const FunctionDecl *FD) {
  703. return getPersistentSummary(RetEffect::MakeNoRet(),
  704. AF.getEmptyMap(),
  705. /*ReceiverEff=*/ArgEffect(DoNothing),
  706. /*DefaultEff=*/ArgEffect(DoNothing),
  707. /*ThisEff=*/ArgEffect(DecRef, ObjKind::OS));
  708. }
  709. const RetainSummary *
  710. RetainSummaryManager::getOSSummaryFreeRule(const FunctionDecl *FD) {
  711. return getPersistentSummary(RetEffect::MakeNoRet(),
  712. AF.getEmptyMap(),
  713. /*ReceiverEff=*/ArgEffect(DoNothing),
  714. /*DefaultEff=*/ArgEffect(DoNothing),
  715. /*ThisEff=*/ArgEffect(Dealloc, ObjKind::OS));
  716. }
  717. const RetainSummary *
  718. RetainSummaryManager::getOSSummaryCreateRule(const FunctionDecl *FD) {
  719. return getPersistentSummary(RetEffect::MakeOwned(ObjKind::OS),
  720. AF.getEmptyMap());
  721. }
  722. const RetainSummary *
  723. RetainSummaryManager::getOSSummaryGetRule(const FunctionDecl *FD) {
  724. return getPersistentSummary(RetEffect::MakeNotOwned(ObjKind::OS),
  725. AF.getEmptyMap());
  726. }
  727. const RetainSummary *
  728. RetainSummaryManager::getCFSummaryCreateRule(const FunctionDecl *FD) {
  729. return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF),
  730. ArgEffects(AF.getEmptyMap()));
  731. }
  732. const RetainSummary *
  733. RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) {
  734. return getPersistentSummary(RetEffect::MakeNotOwned(ObjKind::CF),
  735. ArgEffects(AF.getEmptyMap()),
  736. ArgEffect(DoNothing), ArgEffect(DoNothing));
  737. }
  738. //===----------------------------------------------------------------------===//
  739. // Summary creation for Selectors.
  740. //===----------------------------------------------------------------------===//
  741. std::optional<RetEffect>
  742. RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,
  743. const Decl *D) {
  744. if (hasAnyEnabledAttrOf<NSReturnsRetainedAttr>(D, RetTy))
  745. return ObjCAllocRetE;
  746. if (auto K = hasAnyEnabledAttrOf<CFReturnsRetainedAttr, OSReturnsRetainedAttr,
  747. GeneralizedReturnsRetainedAttr>(D, RetTy))
  748. return RetEffect::MakeOwned(*K);
  749. if (auto K = hasAnyEnabledAttrOf<
  750. CFReturnsNotRetainedAttr, OSReturnsNotRetainedAttr,
  751. GeneralizedReturnsNotRetainedAttr, NSReturnsNotRetainedAttr,
  752. NSReturnsAutoreleasedAttr>(D, RetTy))
  753. return RetEffect::MakeNotOwned(*K);
  754. if (const auto *MD = dyn_cast<CXXMethodDecl>(D))
  755. for (const auto *PD : MD->overridden_methods())
  756. if (auto RE = getRetEffectFromAnnotations(RetTy, PD))
  757. return RE;
  758. return std::nullopt;
  759. }
  760. /// \return Whether the chain of typedefs starting from @c QT
  761. /// has a typedef with a given name @c Name.
  762. static bool hasTypedefNamed(QualType QT,
  763. StringRef Name) {
  764. while (auto *T = QT->getAs<TypedefType>()) {
  765. const auto &Context = T->getDecl()->getASTContext();
  766. if (T->getDecl()->getIdentifier() == &Context.Idents.get(Name))
  767. return true;
  768. QT = T->getDecl()->getUnderlyingType();
  769. }
  770. return false;
  771. }
  772. static QualType getCallableReturnType(const NamedDecl *ND) {
  773. if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
  774. return FD->getReturnType();
  775. } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(ND)) {
  776. return MD->getReturnType();
  777. } else {
  778. llvm_unreachable("Unexpected decl");
  779. }
  780. }
  781. bool RetainSummaryManager::applyParamAnnotationEffect(
  782. const ParmVarDecl *pd, unsigned parm_idx, const NamedDecl *FD,
  783. RetainSummaryTemplate &Template) {
  784. QualType QT = pd->getType();
  785. if (auto K =
  786. hasAnyEnabledAttrOf<NSConsumedAttr, CFConsumedAttr, OSConsumedAttr,
  787. GeneralizedConsumedAttr>(pd, QT)) {
  788. Template->addArg(AF, parm_idx, ArgEffect(DecRef, *K));
  789. return true;
  790. } else if (auto K = hasAnyEnabledAttrOf<
  791. CFReturnsRetainedAttr, OSReturnsRetainedAttr,
  792. OSReturnsRetainedOnNonZeroAttr, OSReturnsRetainedOnZeroAttr,
  793. GeneralizedReturnsRetainedAttr>(pd, QT)) {
  794. // For OSObjects, we try to guess whether the object is created based
  795. // on the return value.
  796. if (K == ObjKind::OS) {
  797. QualType QT = getCallableReturnType(FD);
  798. bool HasRetainedOnZero = pd->hasAttr<OSReturnsRetainedOnZeroAttr>();
  799. bool HasRetainedOnNonZero = pd->hasAttr<OSReturnsRetainedOnNonZeroAttr>();
  800. // The usual convention is to create an object on non-zero return, but
  801. // it's reverted if the typedef chain has a typedef kern_return_t,
  802. // because kReturnSuccess constant is defined as zero.
  803. // The convention can be overwritten by custom attributes.
  804. bool SuccessOnZero =
  805. HasRetainedOnZero ||
  806. (hasTypedefNamed(QT, "kern_return_t") && !HasRetainedOnNonZero);
  807. bool ShouldSplit = !QT.isNull() && !QT->isVoidType();
  808. ArgEffectKind AK = RetainedOutParameter;
  809. if (ShouldSplit && SuccessOnZero) {
  810. AK = RetainedOutParameterOnZero;
  811. } else if (ShouldSplit && (!SuccessOnZero || HasRetainedOnNonZero)) {
  812. AK = RetainedOutParameterOnNonZero;
  813. }
  814. Template->addArg(AF, parm_idx, ArgEffect(AK, ObjKind::OS));
  815. }
  816. // For others:
  817. // Do nothing. Retained out parameters will either point to a +1 reference
  818. // or NULL, but the way you check for failure differs depending on the
  819. // API. Consequently, we don't have a good way to track them yet.
  820. return true;
  821. } else if (auto K = hasAnyEnabledAttrOf<CFReturnsNotRetainedAttr,
  822. OSReturnsNotRetainedAttr,
  823. GeneralizedReturnsNotRetainedAttr>(
  824. pd, QT)) {
  825. Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter, *K));
  826. return true;
  827. }
  828. if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
  829. for (const auto *OD : MD->overridden_methods()) {
  830. const ParmVarDecl *OP = OD->parameters()[parm_idx];
  831. if (applyParamAnnotationEffect(OP, parm_idx, OD, Template))
  832. return true;
  833. }
  834. }
  835. return false;
  836. }
  837. void
  838. RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
  839. const FunctionDecl *FD) {
  840. if (!FD)
  841. return;
  842. assert(Summ && "Must have a summary to add annotations to.");
  843. RetainSummaryTemplate Template(Summ, *this);
  844. // Effects on the parameters.
  845. unsigned parm_idx = 0;
  846. for (auto pi = FD->param_begin(),
  847. pe = FD->param_end(); pi != pe; ++pi, ++parm_idx)
  848. applyParamAnnotationEffect(*pi, parm_idx, FD, Template);
  849. QualType RetTy = FD->getReturnType();
  850. if (std::optional<RetEffect> RetE = getRetEffectFromAnnotations(RetTy, FD))
  851. Template->setRetEffect(*RetE);
  852. if (hasAnyEnabledAttrOf<OSConsumesThisAttr>(FD, RetTy))
  853. Template->setThisEffect(ArgEffect(DecRef, ObjKind::OS));
  854. }
  855. void
  856. RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
  857. const ObjCMethodDecl *MD) {
  858. if (!MD)
  859. return;
  860. assert(Summ && "Must have a valid summary to add annotations to");
  861. RetainSummaryTemplate Template(Summ, *this);
  862. // Effects on the receiver.
  863. if (hasAnyEnabledAttrOf<NSConsumesSelfAttr>(MD, MD->getReturnType()))
  864. Template->setReceiverEffect(ArgEffect(DecRef, ObjKind::ObjC));
  865. // Effects on the parameters.
  866. unsigned parm_idx = 0;
  867. for (auto pi = MD->param_begin(), pe = MD->param_end(); pi != pe;
  868. ++pi, ++parm_idx)
  869. applyParamAnnotationEffect(*pi, parm_idx, MD, Template);
  870. QualType RetTy = MD->getReturnType();
  871. if (std::optional<RetEffect> RetE = getRetEffectFromAnnotations(RetTy, MD))
  872. Template->setRetEffect(*RetE);
  873. }
  874. const RetainSummary *
  875. RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
  876. Selector S, QualType RetTy) {
  877. // Any special effects?
  878. ArgEffect ReceiverEff = ArgEffect(DoNothing, ObjKind::ObjC);
  879. RetEffect ResultEff = RetEffect::MakeNoRet();
  880. // Check the method family, and apply any default annotations.
  881. switch (MD ? MD->getMethodFamily() : S.getMethodFamily()) {
  882. case OMF_None:
  883. case OMF_initialize:
  884. case OMF_performSelector:
  885. // Assume all Objective-C methods follow Cocoa Memory Management rules.
  886. // FIXME: Does the non-threaded performSelector family really belong here?
  887. // The selector could be, say, @selector(copy).
  888. if (cocoa::isCocoaObjectRef(RetTy))
  889. ResultEff = RetEffect::MakeNotOwned(ObjKind::ObjC);
  890. else if (coreFoundation::isCFObjectRef(RetTy)) {
  891. // ObjCMethodDecl currently doesn't consider CF objects as valid return
  892. // values for alloc, new, copy, or mutableCopy, so we have to
  893. // double-check with the selector. This is ugly, but there aren't that
  894. // many Objective-C methods that return CF objects, right?
  895. if (MD) {
  896. switch (S.getMethodFamily()) {
  897. case OMF_alloc:
  898. case OMF_new:
  899. case OMF_copy:
  900. case OMF_mutableCopy:
  901. ResultEff = RetEffect::MakeOwned(ObjKind::CF);
  902. break;
  903. default:
  904. ResultEff = RetEffect::MakeNotOwned(ObjKind::CF);
  905. break;
  906. }
  907. } else {
  908. ResultEff = RetEffect::MakeNotOwned(ObjKind::CF);
  909. }
  910. }
  911. break;
  912. case OMF_init:
  913. ResultEff = ObjCInitRetE;
  914. ReceiverEff = ArgEffect(DecRef, ObjKind::ObjC);
  915. break;
  916. case OMF_alloc:
  917. case OMF_new:
  918. case OMF_copy:
  919. case OMF_mutableCopy:
  920. if (cocoa::isCocoaObjectRef(RetTy))
  921. ResultEff = ObjCAllocRetE;
  922. else if (coreFoundation::isCFObjectRef(RetTy))
  923. ResultEff = RetEffect::MakeOwned(ObjKind::CF);
  924. break;
  925. case OMF_autorelease:
  926. ReceiverEff = ArgEffect(Autorelease, ObjKind::ObjC);
  927. break;
  928. case OMF_retain:
  929. ReceiverEff = ArgEffect(IncRef, ObjKind::ObjC);
  930. break;
  931. case OMF_release:
  932. ReceiverEff = ArgEffect(DecRef, ObjKind::ObjC);
  933. break;
  934. case OMF_dealloc:
  935. ReceiverEff = ArgEffect(Dealloc, ObjKind::ObjC);
  936. break;
  937. case OMF_self:
  938. // -self is handled specially by the ExprEngine to propagate the receiver.
  939. break;
  940. case OMF_retainCount:
  941. case OMF_finalize:
  942. // These methods don't return objects.
  943. break;
  944. }
  945. // If one of the arguments in the selector has the keyword 'delegate' we
  946. // should stop tracking the reference count for the receiver. This is
  947. // because the reference count is quite possibly handled by a delegate
  948. // method.
  949. if (S.isKeywordSelector()) {
  950. for (unsigned i = 0, e = S.getNumArgs(); i != e; ++i) {
  951. StringRef Slot = S.getNameForSlot(i);
  952. if (Slot.substr(Slot.size() - 8).equals_insensitive("delegate")) {
  953. if (ResultEff == ObjCInitRetE)
  954. ResultEff = RetEffect::MakeNoRetHard();
  955. else
  956. ReceiverEff = ArgEffect(StopTrackingHard, ObjKind::ObjC);
  957. }
  958. }
  959. }
  960. if (ReceiverEff.getKind() == DoNothing &&
  961. ResultEff.getKind() == RetEffect::NoRet)
  962. return getDefaultSummary();
  963. return getPersistentSummary(ResultEff, ArgEffects(AF.getEmptyMap()),
  964. ArgEffect(ReceiverEff), ArgEffect(MayEscape));
  965. }
  966. const RetainSummary *
  967. RetainSummaryManager::getClassMethodSummary(const ObjCMessageExpr *ME) {
  968. assert(!ME->isInstanceMessage());
  969. const ObjCInterfaceDecl *Class = ME->getReceiverInterface();
  970. return getMethodSummary(ME->getSelector(), Class, ME->getMethodDecl(),
  971. ME->getType(), ObjCClassMethodSummaries);
  972. }
  973. const RetainSummary *RetainSummaryManager::getInstanceMethodSummary(
  974. const ObjCMessageExpr *ME,
  975. QualType ReceiverType) {
  976. const ObjCInterfaceDecl *ReceiverClass = nullptr;
  977. // We do better tracking of the type of the object than the core ExprEngine.
  978. // See if we have its type in our private state.
  979. if (!ReceiverType.isNull())
  980. if (const auto *PT = ReceiverType->getAs<ObjCObjectPointerType>())
  981. ReceiverClass = PT->getInterfaceDecl();
  982. // If we don't know what kind of object this is, fall back to its static type.
  983. if (!ReceiverClass)
  984. ReceiverClass = ME->getReceiverInterface();
  985. // FIXME: The receiver could be a reference to a class, meaning that
  986. // we should use the class method.
  987. // id x = [NSObject class];
  988. // [x performSelector:... withObject:... afterDelay:...];
  989. Selector S = ME->getSelector();
  990. const ObjCMethodDecl *Method = ME->getMethodDecl();
  991. if (!Method && ReceiverClass)
  992. Method = ReceiverClass->getInstanceMethod(S);
  993. return getMethodSummary(S, ReceiverClass, Method, ME->getType(),
  994. ObjCMethodSummaries);
  995. }
  996. const RetainSummary *
  997. RetainSummaryManager::getMethodSummary(Selector S,
  998. const ObjCInterfaceDecl *ID,
  999. const ObjCMethodDecl *MD, QualType RetTy,
  1000. ObjCMethodSummariesTy &CachedSummaries) {
  1001. // Objective-C method summaries are only applicable to ObjC and CF objects.
  1002. if (!TrackObjCAndCFObjects)
  1003. return getDefaultSummary();
  1004. // Look up a summary in our summary cache.
  1005. const RetainSummary *Summ = CachedSummaries.find(ID, S);
  1006. if (!Summ) {
  1007. Summ = getStandardMethodSummary(MD, S, RetTy);
  1008. // Annotations override defaults.
  1009. updateSummaryFromAnnotations(Summ, MD);
  1010. // Memoize the summary.
  1011. CachedSummaries[ObjCSummaryKey(ID, S)] = Summ;
  1012. }
  1013. return Summ;
  1014. }
  1015. void RetainSummaryManager::InitializeClassMethodSummaries() {
  1016. ArgEffects ScratchArgs = AF.getEmptyMap();
  1017. // Create the [NSAssertionHandler currentHander] summary.
  1018. addClassMethSummary("NSAssertionHandler", "currentHandler",
  1019. getPersistentSummary(RetEffect::MakeNotOwned(ObjKind::ObjC),
  1020. ScratchArgs));
  1021. // Create the [NSAutoreleasePool addObject:] summary.
  1022. ScratchArgs = AF.add(ScratchArgs, 0, ArgEffect(Autorelease));
  1023. addClassMethSummary("NSAutoreleasePool", "addObject",
  1024. getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs,
  1025. ArgEffect(DoNothing),
  1026. ArgEffect(Autorelease)));
  1027. }
  1028. void RetainSummaryManager::InitializeMethodSummaries() {
  1029. ArgEffects ScratchArgs = AF.getEmptyMap();
  1030. // Create the "init" selector. It just acts as a pass-through for the
  1031. // receiver.
  1032. const RetainSummary *InitSumm = getPersistentSummary(
  1033. ObjCInitRetE, ScratchArgs, ArgEffect(DecRef, ObjKind::ObjC));
  1034. addNSObjectMethSummary(GetNullarySelector("init", Ctx), InitSumm);
  1035. // awakeAfterUsingCoder: behaves basically like an 'init' method. It
  1036. // claims the receiver and returns a retained object.
  1037. addNSObjectMethSummary(GetUnarySelector("awakeAfterUsingCoder", Ctx),
  1038. InitSumm);
  1039. // The next methods are allocators.
  1040. const RetainSummary *AllocSumm = getPersistentSummary(ObjCAllocRetE,
  1041. ScratchArgs);
  1042. const RetainSummary *CFAllocSumm =
  1043. getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF), ScratchArgs);
  1044. // Create the "retain" selector.
  1045. RetEffect NoRet = RetEffect::MakeNoRet();
  1046. const RetainSummary *Summ = getPersistentSummary(
  1047. NoRet, ScratchArgs, ArgEffect(IncRef, ObjKind::ObjC));
  1048. addNSObjectMethSummary(GetNullarySelector("retain", Ctx), Summ);
  1049. // Create the "release" selector.
  1050. Summ = getPersistentSummary(NoRet, ScratchArgs,
  1051. ArgEffect(DecRef, ObjKind::ObjC));
  1052. addNSObjectMethSummary(GetNullarySelector("release", Ctx), Summ);
  1053. // Create the -dealloc summary.
  1054. Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(Dealloc,
  1055. ObjKind::ObjC));
  1056. addNSObjectMethSummary(GetNullarySelector("dealloc", Ctx), Summ);
  1057. // Create the "autorelease" selector.
  1058. Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(Autorelease,
  1059. ObjKind::ObjC));
  1060. addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
  1061. // For NSWindow, allocated objects are (initially) self-owned.
  1062. // FIXME: For now we opt for false negatives with NSWindow, as these objects
  1063. // self-own themselves. However, they only do this once they are displayed.
  1064. // Thus, we need to track an NSWindow's display status.
  1065. // This is tracked in <rdar://problem/6062711>.
  1066. // See also http://llvm.org/bugs/show_bug.cgi?id=3714.
  1067. const RetainSummary *NoTrackYet =
  1068. getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs,
  1069. ArgEffect(StopTracking), ArgEffect(StopTracking));
  1070. addClassMethSummary("NSWindow", "alloc", NoTrackYet);
  1071. // For NSPanel (which subclasses NSWindow), allocated objects are not
  1072. // self-owned.
  1073. // FIXME: For now we don't track NSPanels. object for the same reason
  1074. // as for NSWindow objects.
  1075. addClassMethSummary("NSPanel", "alloc", NoTrackYet);
  1076. // For NSNull, objects returned by +null are singletons that ignore
  1077. // retain/release semantics. Just don't track them.
  1078. // <rdar://problem/12858915>
  1079. addClassMethSummary("NSNull", "null", NoTrackYet);
  1080. // Don't track allocated autorelease pools, as it is okay to prematurely
  1081. // exit a method.
  1082. addClassMethSummary("NSAutoreleasePool", "alloc", NoTrackYet);
  1083. addClassMethSummary("NSAutoreleasePool", "allocWithZone", NoTrackYet, false);
  1084. addClassMethSummary("NSAutoreleasePool", "new", NoTrackYet);
  1085. // Create summaries QCRenderer/QCView -createSnapShotImageOfType:
  1086. addInstMethSummary("QCRenderer", AllocSumm, "createSnapshotImageOfType");
  1087. addInstMethSummary("QCView", AllocSumm, "createSnapshotImageOfType");
  1088. // Create summaries for CIContext, 'createCGImage' and
  1089. // 'createCGLayerWithSize'. These objects are CF objects, and are not
  1090. // automatically garbage collected.
  1091. addInstMethSummary("CIContext", CFAllocSumm, "createCGImage", "fromRect");
  1092. addInstMethSummary("CIContext", CFAllocSumm, "createCGImage", "fromRect",
  1093. "format", "colorSpace");
  1094. addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize", "info");
  1095. }
  1096. const RetainSummary *
  1097. RetainSummaryManager::getMethodSummary(const ObjCMethodDecl *MD) {
  1098. const ObjCInterfaceDecl *ID = MD->getClassInterface();
  1099. Selector S = MD->getSelector();
  1100. QualType ResultTy = MD->getReturnType();
  1101. ObjCMethodSummariesTy *CachedSummaries;
  1102. if (MD->isInstanceMethod())
  1103. CachedSummaries = &ObjCMethodSummaries;
  1104. else
  1105. CachedSummaries = &ObjCClassMethodSummaries;
  1106. return getMethodSummary(S, ID, MD, ResultTy, *CachedSummaries);
  1107. }