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