RetainSummaryManager.cpp 47 KB

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