]> granicus.if.org Git - clang/commitdiff
[analyzer] Only allocate retain summaries for interesting functions/messages. This...
authorJordy Rose <jediknil@belkadan.com>
Tue, 23 Aug 2011 04:27:15 +0000 (04:27 +0000)
committerJordy Rose <jediknil@belkadan.com>
Tue, 23 Aug 2011 04:27:15 +0000 (04:27 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138320 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/CFRefCount.cpp

index 4cb2950494776d304d72fcb43abe9b38097b9e1a..457773759887e0869c506b36268f3902c3e499bc 100644 (file)
@@ -160,6 +160,10 @@ public:
            K == OwnedWhenTrackedReceiver;
   }
 
+  bool operator==(const RetEffect &Other) const {
+    return K == Other.K && O == Other.O;
+  }
+
   static RetEffect MakeOwnedWhenTrackedReceiver() {
     return RetEffect(OwnedWhenTrackedReceiver, ObjC);
   }
@@ -452,6 +456,14 @@ public:
   /// getReceiverEffect - Returns the effect on the receiver of the call.
   ///  This is only meaningful if the summary applies to an ObjCMessageExpr*.
   ArgEffect getReceiverEffect() const { return Receiver; }
+
+  /// Test if two retain summaries are identical. Note that merely equivalent
+  /// summaries are not necessarily identical (for example, if an explicit 
+  /// argument effect matches the default effect).
+  bool operator==(const RetainSummary &Other) const {
+    return Args == Other.Args && DefaultArgEffect == Other.DefaultArgEffect &&
+           Receiver == Other.Receiver && Ret == Other.Ret;
+  }
 };
 } // end anonymous namespace
 
@@ -654,11 +666,6 @@ class RetainSummaryManager {
 public:
   RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
 
-  RetainSummary *getDefaultSummary() {
-    RetainSummary *Summ = (RetainSummary*) BPAlloc.Allocate<RetainSummary>();
-    return new (Summ) RetainSummary(DefaultSummary);
-  }
-
   RetainSummary* getUnarySummary(const FunctionType* FT, UnaryFuncKind func);
 
   RetainSummary* getCFSummaryCreateRule(const FunctionDecl *FD);
@@ -828,10 +835,10 @@ public:
   RetainSummary* getCommonMethodSummary(const ObjCMethodDecl *MD,
                                         Selector S, QualType RetTy);
 
-  void updateSummaryFromAnnotations(RetainSummary &Summ,
+  void updateSummaryFromAnnotations(RetainSummary *&Summ,
                                     const ObjCMethodDecl *MD);
 
-  void updateSummaryFromAnnotations(RetainSummary &Summ,
+  void updateSummaryFromAnnotations(RetainSummary *&Summ,
                                     const FunctionDecl *FD);
 
   bool isGCEnabled() const { return GCEnabled; }
@@ -1078,12 +1085,8 @@ RetainSummary* RetainSummaryManager::getSummary(const FunctionDecl *FD) {
   }
   while (0);
 
-  if (!S)
-    S = getDefaultSummary();
-
   // Annotations override defaults.
-  assert(S);
-  updateSummaryFromAnnotations(*S, FD);
+  updateSummaryFromAnnotations(S, FD);
 
   FuncSummaries[FD] = S;
   return S;
@@ -1154,26 +1157,30 @@ RetainSummaryManager::getInitMethodSummary(QualType RetTy) {
       coreFoundation::isCFObjectRef(RetTy))
     return getPersistentSummary(ObjCInitRetE, DecRefMsg);
 
-  return getDefaultSummary();
+  return 0;
 }
 
 void
-RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
+RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ,
                                                    const FunctionDecl *FD) {
   if (!FD)
     return;
 
+  RetainSummary BasedOnDefault(DefaultSummary);
+  if (!Summ)
+    Summ = &BasedOnDefault;
+
   // Effects on the parameters.
   unsigned parm_idx = 0;
   for (FunctionDecl::param_const_iterator pi = FD->param_begin(), 
          pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) {
     const ParmVarDecl *pd = *pi;
     if (pd->getAttr<NSConsumedAttr>()) {
-      if (!GCEnabled)
-        Summ.addArg(AF, parm_idx, DecRef);      
-    }
-    else if(pd->getAttr<CFConsumedAttr>()) {
-      Summ.addArg(AF, parm_idx, DecRef);      
+      if (!GCEnabled) {
+        Summ->addArg(AF, parm_idx, DecRef);      
+      }
+    } else if (pd->getAttr<CFConsumedAttr>()) {
+      Summ->addArg(AF, parm_idx, DecRef);      
     }   
   }
   
@@ -1182,40 +1189,50 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
   // Determine if there is a special return effect for this method.
   if (cocoa::isCocoaObjectRef(RetTy)) {
     if (FD->getAttr<NSReturnsRetainedAttr>()) {
-      Summ.setRetEffect(ObjCAllocRetE);
+      Summ->setRetEffect(ObjCAllocRetE);
     }
     else if (FD->getAttr<CFReturnsRetainedAttr>()) {
-      Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
+      Summ->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
     }
     else if (FD->getAttr<NSReturnsNotRetainedAttr>()) {
-      Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
+      Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
     }
     else if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
-      Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
+      Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
     }
-  }
-  else if (RetTy->getAs<PointerType>()) {
+  } else if (RetTy->getAs<PointerType>()) {
     if (FD->getAttr<CFReturnsRetainedAttr>()) {
-      Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
+      Summ->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
     }
     else if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
-      Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
+      Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
     }
   }
+
+  if (Summ == &BasedOnDefault) {
+    if (!(*Summ == DefaultSummary))
+      Summ = copySummary(Summ);
+    else
+      Summ = 0;
+  }
 }
 
 void
-RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
+RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ,
                                                   const ObjCMethodDecl *MD) {
   if (!MD)
     return;
 
+  RetainSummary BasedOnDefault = DefaultSummary;
+  if (!Summ)
+    Summ = &BasedOnDefault;
+
   bool isTrackedLoc = false;
 
   // Effects on the receiver.
   if (MD->getAttr<NSConsumesSelfAttr>()) {
     if (!GCEnabled)
-      Summ.setReceiverEffect(DecRefMsg);      
+      Summ->setReceiverEffect(DecRefMsg);      
   }
   
   // Effects on the parameters.
@@ -1225,21 +1242,21 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
     const ParmVarDecl *pd = *pi;
     if (pd->getAttr<NSConsumedAttr>()) {
       if (!GCEnabled)
-        Summ.addArg(AF, parm_idx, DecRef);      
+        Summ->addArg(AF, parm_idx, DecRef);      
     }
     else if(pd->getAttr<CFConsumedAttr>()) {
-      Summ.addArg(AF, parm_idx, DecRef);      
+      Summ->addArg(AF, parm_idx, DecRef);      
     }   
   }
   
   // Determine if there is a special return effect for this method.
   if (cocoa::isCocoaObjectRef(MD->getResultType())) {
     if (MD->getAttr<NSReturnsRetainedAttr>()) {
-      Summ.setRetEffect(ObjCAllocRetE);
+      Summ->setRetEffect(ObjCAllocRetE);
       return;
     }
     if (MD->getAttr<NSReturnsNotRetainedAttr>()) {
-      Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
+      Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
       return;
     }
 
@@ -1251,9 +1268,16 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
 
   if (isTrackedLoc) {
     if (MD->getAttr<CFReturnsRetainedAttr>())
-      Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
+      Summ->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
     else if (MD->getAttr<CFReturnsNotRetainedAttr>())
-      Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
+      Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
+  }
+
+  if (Summ == &BasedOnDefault) {
+    if (!(*Summ == DefaultSummary))
+      Summ = copySummary(Summ);
+    else
+      Summ = 0;
   }
 }
 
@@ -1310,7 +1334,7 @@ RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl *MD,
   }
 
   if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing)
-    return getDefaultSummary();
+    return 0;
 
   return getPersistentSummary(RetEffect::MakeNoRet(), ReceiverEff, MayEscape);
 }
@@ -1355,8 +1379,7 @@ RetainSummaryManager::getInstanceMethodSummary(const ObjCMessage &msg,
 
   // FIXME: The receiver could be a reference to a class, meaning that
   //  we should use the class method.
-  RetainSummary *Summ = getInstanceMethodSummary(msg, ID);
-  return Summ ? Summ : getDefaultSummary();
+  return getInstanceMethodSummary(msg, ID);
 }
 
 RetainSummary*
@@ -1379,7 +1402,7 @@ RetainSummaryManager::getInstanceMethodSummary(Selector S,
       Summ = getCommonMethodSummary(MD, S, RetTy);
 
     // Annotations override defaults.
-    updateSummaryFromAnnotations(*Summ, MD);
+    updateSummaryFromAnnotations(Summ, MD);
 
     // Memoize the summary.
     ObjCMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
@@ -1399,8 +1422,10 @@ RetainSummaryManager::getClassMethodSummary(Selector S, IdentifierInfo *ClsName,
 
   if (!Summ) {
     Summ = getCommonMethodSummary(MD, S, RetTy);
+
     // Annotations override defaults.
-    updateSummaryFromAnnotations(*Summ, MD);
+    updateSummaryFromAnnotations(Summ, MD);
+
     // Memoize the summary.
     ObjCClassMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
   }
@@ -2743,10 +2768,13 @@ void CFRefCount::evalReturn(ExplodedNodeSet &Dst,
   Decl const *CD = &Pred->getCodeDecl();
 
   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
-    const RetainSummary &Summ = *Summaries.getMethodSummary(MD);
+    // Unlike regular functions, /all/ ObjC methods are assumed to always
+    // follow Cocoa retain-count conventions, not just those with special
+    // names or attributes.
+    const RetainSummary *Summ = Summaries.getMethodSummary(MD);
+    RetEffect RE = Summ ? Summ->getRetEffect() : RetEffect::MakeNoRet();
     return evalReturnWithRetEffect(Dst, Eng, Builder, S, 
-                                   Pred, Summ.getRetEffect(), X,
-                                   Sym, state);
+                                   Pred, RE, X, Sym, state);
   }
 
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {