]> granicus.if.org Git - clang/commitdiff
[analyzer] Fix potential crasher with RAII. No functionality change. (No test because...
authorJordy Rose <jediknil@belkadan.com>
Wed, 24 Aug 2011 09:02:37 +0000 (09:02 +0000)
committerJordy Rose <jediknil@belkadan.com>
Wed, 24 Aug 2011 09:02:37 +0000 (09:02 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138430 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/CFRefCount.cpp

index 11d240c31e380143b5a816c831afcc898e68cb1b..8a7d3acbbdae7b818dd9eb5d7fd7d8d0a553621d 100644 (file)
@@ -854,6 +854,37 @@ public:
   }
 };
 
+// Used to avoid allocating long-term (BPAlloc'd) memory for default retain
+// summaries. If a function or method looks like it has a default summary, but
+// it has annotations, the annotations are added to the stack-based template
+// and then copied into managed memory.
+class RetainSummaryTemplate {
+  RetainSummaryManager &Manager;
+  RetainSummary *&RealSummary;
+  RetainSummary ScratchSummary;
+  bool Accessed;
+public:
+  RetainSummaryTemplate(RetainSummary *&real, const RetainSummary &base,
+                        RetainSummaryManager &manager)
+  : Manager(manager), RealSummary(real), ScratchSummary(base), Accessed(false)
+  {}
+
+  ~RetainSummaryTemplate() {
+    if (!RealSummary && Accessed)
+      RealSummary = Manager.copySummary(&ScratchSummary);
+  }
+
+  RetainSummary &operator*() {
+    Accessed = true;
+    return RealSummary ? *RealSummary : ScratchSummary;
+  }
+
+  RetainSummary *operator->() {
+    Accessed = true;
+    return RealSummary ? RealSummary : &ScratchSummary;
+  }
+};
+
 } // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
@@ -1166,9 +1197,7 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ,
   if (!FD)
     return;
 
-  RetainSummary BasedOnDefault(DefaultSummary);
-  if (!Summ)
-    Summ = &BasedOnDefault;
+  RetainSummaryTemplate Template(Summ, DefaultSummary, *this);
 
   // Effects on the parameters.
   unsigned parm_idx = 0;
@@ -1177,10 +1206,10 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ,
     const ParmVarDecl *pd = *pi;
     if (pd->getAttr<NSConsumedAttr>()) {
       if (!GCEnabled) {
-        Summ->addArg(AF, parm_idx, DecRef);      
+        Template->addArg(AF, parm_idx, DecRef);      
       }
     } else if (pd->getAttr<CFConsumedAttr>()) {
-      Summ->addArg(AF, parm_idx, DecRef);      
+      Template->addArg(AF, parm_idx, DecRef);      
     }   
   }
   
@@ -1189,32 +1218,25 @@ 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);
+      Template->setRetEffect(ObjCAllocRetE);
     }
     else if (FD->getAttr<CFReturnsRetainedAttr>()) {
-      Summ->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
+      Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
     }
     else if (FD->getAttr<NSReturnsNotRetainedAttr>()) {
-      Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
+      Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
     }
     else if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
-      Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
+      Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
     }
   } else if (RetTy->getAs<PointerType>()) {
     if (FD->getAttr<CFReturnsRetainedAttr>()) {
-      Summ->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
+      Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
     }
     else if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
-      Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
+      Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
     }
   }
-
-  if (Summ == &BasedOnDefault) {
-    if (!(*Summ == DefaultSummary))
-      Summ = copySummary(Summ);
-    else
-      Summ = 0;
-  }
 }
 
 void
@@ -1223,16 +1245,14 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ,
   if (!MD)
     return;
 
-  RetainSummary BasedOnDefault = DefaultSummary;
-  if (!Summ)
-    Summ = &BasedOnDefault;
+  RetainSummaryTemplate Template(Summ, DefaultSummary, *this);
 
   bool isTrackedLoc = false;
 
   // Effects on the receiver.
   if (MD->getAttr<NSConsumesSelfAttr>()) {
     if (!GCEnabled)
-      Summ->setReceiverEffect(DecRefMsg);      
+      Template->setReceiverEffect(DecRefMsg);      
   }
   
   // Effects on the parameters.
@@ -1242,42 +1262,34 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ,
     const ParmVarDecl *pd = *pi;
     if (pd->getAttr<NSConsumedAttr>()) {
       if (!GCEnabled)
-        Summ->addArg(AF, parm_idx, DecRef);      
+        Template->addArg(AF, parm_idx, DecRef);      
     }
     else if(pd->getAttr<CFConsumedAttr>()) {
-      Summ->addArg(AF, parm_idx, DecRef);      
+      Template->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);
+      Template->setRetEffect(ObjCAllocRetE);
       return;
     }
     if (MD->getAttr<NSReturnsNotRetainedAttr>()) {
-      Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
+      Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
       return;
     }
 
     isTrackedLoc = true;
-  }
-
-  if (!isTrackedLoc)
+  } else {
     isTrackedLoc = MD->getResultType()->getAs<PointerType>() != NULL;
+  }
 
   if (isTrackedLoc) {
     if (MD->getAttr<CFReturnsRetainedAttr>())
-      Summ->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
+      Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
     else if (MD->getAttr<CFReturnsNotRetainedAttr>())
-      Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
-  }
-
-  if (Summ == &BasedOnDefault) {
-    if (!(*Summ == DefaultSummary))
-      Summ = copySummary(Summ);
-    else
-      Summ = 0;
+      Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
   }
 }