[cfe-commits] r50214 - /cfe/trunk/lib/Analysis/CFRefCount.cpp

Ted Kremenek kremenek at apple.com
Thu Apr 24 10:22:33 PDT 2008


Author: kremenek
Date: Thu Apr 24 12:22:33 2008
New Revision: 50214

URL: http://llvm.org/viewvc/llvm-project?rev=50214&view=rev
Log:
CF reference count checker: handle variadic functions that allocate CF objects.
This fixes <rdar://problem/5886141>.

Part of this change resulted in creating sparser summaries.  I also added
some more comments and did some minor code cleanups.

Modified:
    cfe/trunk/lib/Analysis/CFRefCount.cpp

Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=50214&r1=50213&r2=50214&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Thu Apr 24 12:22:33 2008
@@ -42,14 +42,16 @@
 
 namespace {  
   enum ArgEffect { IncRef, DecRef, DoNothing };
-  typedef std::vector<ArgEffect> ArgEffects;
+  typedef std::vector<std::pair<unsigned,ArgEffect> > ArgEffects;
 }
 
 namespace llvm {
   template <> struct FoldingSetTrait<ArgEffects> {
     static void Profile(const ArgEffects& X, FoldingSetNodeID& ID) {
-      for (ArgEffects::const_iterator I = X.begin(), E = X.end(); I!= E; ++I)
-        ID.AddInteger((unsigned) *I);
+      for (ArgEffects::const_iterator I = X.begin(), E = X.end(); I!= E; ++I) {
+        ID.AddInteger(I->first);
+        ID.AddInteger((unsigned) I->second);
+      }
     }    
   };
 } // end llvm namespace
@@ -98,8 +100,25 @@
   unsigned getNumArgs() const { return Args->size(); }
   
   ArgEffect getArg(unsigned idx) const {
-    assert (idx < getNumArgs());
-    return (*Args)[idx];
+    if (!Args)
+      return DoNothing;
+    
+    // If Args is present, it is likely to contain only 1 element.
+    // Just do a linear search.  Do it from the back because functions with
+    // large numbers of arguments will be tail heavy with respect to which
+    // argument they actually modify with respect to the reference count.
+    
+    for (ArgEffects::reverse_iterator I=Args->rbegin(), E=Args->rend();
+           I!=E; ++I) {
+      
+      if (idx > I->first)
+        return DoNothing;
+      
+      if (idx == I->first)
+        return I->second;
+    }
+    
+    return DoNothing;
   }
   
   RetEffect getRet() const {
@@ -132,8 +151,7 @@
   SummaryMapTy SummaryMap;  
   AESetTy AESet;  
   llvm::BumpPtrAllocator BPAlloc;  
-  ArgEffects ScratchArgs;
-  
+  ArgEffects ScratchArgs;  
   
   ArgEffects*   getArgEffects();
 
@@ -145,10 +163,7 @@
   CFRefSummary* getCFSummaryGetRule(FunctionTypeProto* FT);  
   
   CFRefSummary* getPersistentSummary(ArgEffects* AE, RetEffect RE);
-  
-  void FillDoNothing(unsigned Args);
-
-  
+    
 public:
   CFRefSummaryManager(ASTContext& ctx) : Ctx(ctx) {}
   ~CFRefSummaryManager();
@@ -174,14 +189,22 @@
 
 ArgEffects* CFRefSummaryManager::getArgEffects() {
 
+  if (ScratchArgs.empty())
+    return NULL;
+  
+  // Compute a profile for a non-empty ScratchArgs.
+  
   llvm::FoldingSetNodeID profile;
+    
   profile.Add(ScratchArgs);
   void* InsertPos;
   
+  // Look up the uniqued copy, or create a new one.
+  
   llvm::FoldingSetNodeWrapper<ArgEffects>* E =
     AESet.FindNodeOrInsertPos(profile, InsertPos);
   
-  if (E) {    
+  if (E) {
     ScratchArgs.clear();
     return &E->getValue();
   }
@@ -199,15 +222,18 @@
 CFRefSummary* CFRefSummaryManager::getPersistentSummary(ArgEffects* AE,
                                                         RetEffect RE) {
   
+  // Generate a profile for the summary.
   llvm::FoldingSetNodeID profile;
   CFRefSummary::Profile(profile, AE, RE);
-  void* InsertPos;
   
+  // Look up the uniqued summary, or create one if it doesn't exist.
+  void* InsertPos;  
   CFRefSummary* Summ = SummarySet.FindNodeOrInsertPos(profile, InsertPos);
   
   if (Summ)
     return Summ;
   
+  // Create the summary and return it.
   Summ = (CFRefSummary*) BPAlloc.Allocate<CFRefSummary>();
   new (Summ) CFRefSummary(AE, RE);
   SummarySet.InsertNode(Summ, InsertPos);
@@ -224,33 +250,14 @@
   if (!Loc.isFileID())
     return NULL;
   
-  { // Look into our cache of summaries to see if we have already computed
-    // a summary for this FunctionDecl.
-      
-    SummaryMapTy::iterator I = SummaryMap.find(FD);
-    
-    if (I != SummaryMap.end())
-      return I->second;
-  }
-  
-#if 0
-  SourceManager& SrcMgr = Ctx.getSourceManager();
-  unsigned fid = Loc.getFileID();
-  const FileEntry* FE = SrcMgr.getFileEntryForID(fid);
-  
-  if (!FE)
-    return NULL;
-  
-  const char* DirName = FE->getDir()->getName();  
-  assert (DirName);
-  assert (strlen(DirName) > 0);
-  
-  if (!strstr(DirName, "CoreFoundation")) {
-    SummaryMap[FD] = NULL;
-    return NULL;
-  }
-#endif
-  
+
+  // Look up a summary in our cache of FunctionDecls -> Summaries.
+  SummaryMapTy::iterator I = SummaryMap.find(FD);
+
+  if (I != SummaryMap.end())
+    return I->second;
+
+  // No summary.  Generate one.
   const char* FName = FD->getIdentifier()->getName();
     
   if (FName[0] == 'C' && FName[1] == 'F') {
@@ -258,7 +265,8 @@
     SummaryMap[FD] = S;
     return S;
   }
-  
+
+  // Function has no ref-count effects.  Return the NULL summary.
   return NULL;  
 }
 
@@ -331,7 +339,7 @@
     
     // The function's interface checks out.  Generate a canned summary.    
     assert (ScratchArgs.empty());
-    ScratchArgs.push_back(IncRef);
+    ScratchArgs.push_back(std::make_pair(0, IncRef));
     return getPersistentSummary(getArgEffects(), RetEffect::MakeAlias(0));
   }
   else {
@@ -341,7 +349,7 @@
       return NULL;
     
     assert (ScratchArgs.empty());
-    ScratchArgs.push_back(DecRef);
+    ScratchArgs.push_back(std::make_pair(0, DecRef));
     return getPersistentSummary(getArgEffects(), RetEffect::MakeNoRet());
   }
 }
@@ -369,12 +377,6 @@
   
   return true;
 }
-  
-void CFRefSummaryManager::FillDoNothing(unsigned Args) {
-  for (unsigned i = 0; i != Args; ++i)
-    ScratchArgs.push_back(DoNothing);
-}
-
 
 CFRefSummary*
 CFRefSummaryManager::getCFSummaryCreateRule(FunctionTypeProto* FT) {
@@ -382,12 +384,10 @@
   if (!isCFRefType(FT->getResultType()))
     return NULL;
 
-  assert (ScratchArgs.empty());
-  
   // FIXME: Add special-cases for functions that retain/release.  For now
   //  just handle the default case.
-  
-  FillDoNothing(FT->getNumArgs());  
+
+  assert (ScratchArgs.empty());
   return getPersistentSummary(getArgEffects(), RetEffect::MakeOwned());
 }
 
@@ -405,12 +405,10 @@
   if (!isCFRefType(RetTy) && !RetTy->isPointerType())
     return NULL;
   
-  assert (ScratchArgs.empty());
-  
   // FIXME: Add special-cases for functions that retain/release.  For now
   //  just handle the default case.
   
-  FillDoNothing(FT->getNumArgs());  
+  assert (ScratchArgs.empty());  
   return getPersistentSummary(getArgEffects(), RetEffect::MakeNotOwned());
 }
 





More information about the cfe-commits mailing list