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