[cfe-commits] r50829 - in /cfe/trunk: lib/Analysis/CFRefCount.cpp test/Analysis-Apple/CFDate.m

Ted Kremenek kremenek at apple.com
Wed May 7 13:06:42 PDT 2008


Author: kremenek
Date: Wed May  7 15:06:41 2008
New Revision: 50829

URL: http://llvm.org/viewvc/llvm-project?rev=50829&view=rev
Log:
Expand the CF retain checker to allow the Create/Get rule to apply to any
function that returns a CFxxxRef, not just functions whose name begins with
CF.  This implements <rdar://problem/5917879>.

Added test case for this feature.

Updated calls to CStrInCStrNoCase to swap their arguments, per compatibility
with strcasestr.

Modified:
    cfe/trunk/lib/Analysis/CFRefCount.cpp
    cfe/trunk/test/Analysis-Apple/CFDate.m

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

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Wed May  7 15:06:41 2008
@@ -45,6 +45,49 @@
   return Ctx.Selectors.getSelector(1, &II);
 }
 
+static bool isCFRefType(QualType T) {
+  
+  if (!T->isPointerType())
+    return false;
+  
+  // Check the typedef for the name "CF" and the substring "Ref".
+  
+  TypedefType* TD = dyn_cast<TypedefType>(T.getTypePtr());
+  
+  if (!TD)
+    return false;
+  
+  const char* TDName = TD->getDecl()->getIdentifier()->getName();
+  assert (TDName);
+  
+  if (TDName[0] != 'C' || TDName[1] != 'F')
+    return false;
+  
+  if (strstr(TDName, "Ref") == 0)
+    return false;
+  
+  return true;
+}
+
+static bool isNSType(QualType T) {
+  
+  if (!T->isPointerType())
+    return false;
+  
+  ObjCInterfaceType* OT = dyn_cast<ObjCInterfaceType>(T.getTypePtr());
+  
+  if (!OT)
+    return false;
+  
+  const char* ClsName = OT->getDecl()->getIdentifier()->getName();
+  assert (ClsName);
+  
+  if (ClsName[0] != 'N' || ClsName[1] != 'S')
+    return false;
+  
+  return true;
+}
+
 //===----------------------------------------------------------------------===//
 // Symbolic Evaluation of Reference Counting Logic
 //===----------------------------------------------------------------------===//
@@ -383,8 +426,12 @@
     
   RetainSummary *S = 0;
   
-  if (FName[0] == 'C' && FName[1] == 'F')
-    S = getCFSummary(FD, FName);
+  FunctionType* FT = dyn_cast<FunctionType>(FD->getType());
+  
+  if (FT && isCFRefType(FT->getResultType()))
+    S = getCFSummary(FD, FName);          
+  else if (FName[0] == 'C' && FName[1] == 'F')
+    S = getCFSummary(FD, FName);  
   else if (FName[0] == 'N' && FName[1] == 'S')
     S = getNSSummary(FD, FName);
 
@@ -405,7 +452,8 @@
 RetainSummary* RetainSummaryManager::getCFSummary(FunctionDecl* FD,
                                                   const char* FName) {
 
-  FName += 2;
+  if (FName[0] == 'C' && FName[1] == 'F')
+    FName += 2;
 
   if (strcmp(FName, "Retain") == 0)
     return getUnarySummary(FD, cfretain);
@@ -470,53 +518,10 @@
   }
 }
 
-static bool isCFRefType(QualType T) {
-  
-  if (!T->isPointerType())
-    return false;
-  
-  // Check the typedef for the name "CF" and the substring "Ref".
-  
-  TypedefType* TD = dyn_cast<TypedefType>(T.getTypePtr());
-  
-  if (!TD)
-    return false;
-  
-  const char* TDName = TD->getDecl()->getIdentifier()->getName();
-  assert (TDName);
-  
-  if (TDName[0] != 'C' || TDName[1] != 'F')
-    return false;
-  
-  if (strstr(TDName, "Ref") == 0)
-    return false;
-  
-  return true;
-}
-
-static bool isNSType(QualType T) {
-  
-  if (!T->isPointerType())
-    return false;
-  
-  ObjCInterfaceType* OT = dyn_cast<ObjCInterfaceType>(T.getTypePtr());
-  
-  if (!OT)
-    return false;
-  
-  const char* ClsName = OT->getDecl()->getIdentifier()->getName();
-  assert (ClsName);
-  
-  if (ClsName[0] != 'N' || ClsName[1] != 'S')
-    return false;
-  
-  return true;
-}
-
 RetainSummary* RetainSummaryManager::getCFSummaryCreateRule(FunctionDecl* FD) {
  
-  FunctionTypeProto* FT =
-    dyn_cast<FunctionTypeProto>(FD->getType().getTypePtr());
+  FunctionType* FT =
+    dyn_cast<FunctionType>(FD->getType().getTypePtr());
   
   if (FT && !isCFRefType(FT->getResultType()))
     return 0;
@@ -530,8 +535,8 @@
 
 RetainSummary* RetainSummaryManager::getCFSummaryGetRule(FunctionDecl* FD) {
   
-  FunctionTypeProto* FT =
-    dyn_cast<FunctionTypeProto>(FD->getType().getTypePtr());
+  FunctionType* FT =
+    dyn_cast<FunctionType>(FD->getType().getTypePtr());
   
   if (FT) {
     QualType RetTy = FT->getResultType();
@@ -606,8 +611,8 @@
   if (!isNSType(ME->getReceiver()->getType()))
     return 0;
   
-  if (CStrInCStrNoCase("create", s) || CStrInCStrNoCase("copy", s)  || 
-      CStrInCStrNoCase("new", s)) {
+  if (CStrInCStrNoCase(s, "create") || CStrInCStrNoCase(s, "copy")  || 
+      CStrInCStrNoCase(s, "new")) {
     
     RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet()
                                 : RetEffect::MakeOwned();  

Modified: cfe/trunk/test/Analysis-Apple/CFDate.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis-Apple/CFDate.m?rev=50829&r1=50828&r2=50829&view=diff

==============================================================================
--- cfe/trunk/test/Analysis-Apple/CFDate.m (original)
+++ cfe/trunk/test/Analysis-Apple/CFDate.m Wed May  7 15:06:41 2008
@@ -94,3 +94,16 @@
   date = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent()); 
   return date;
 }
+
+// Generalization of Create rule.  MyDateCreate returns a CFXXXTypeRef, and
+// has the word create.
+
+CFDateRef MyDateCreate();
+
+CFDateRef f8() {
+  CFDateRef date = MyDateCreate();
+  CFRetain(date);  
+  return date; // expected-warning{{leak}}
+}
+
+





More information about the cfe-commits mailing list