]> granicus.if.org Git - clang/commitdiff
Implement ownership attribute 'objc_ownership_make_collectable'. This allows one
authorTed Kremenek <kremenek@apple.com>
Tue, 28 Apr 2009 22:32:26 +0000 (22:32 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 28 Apr 2009 22:32:26 +0000 (22:32 +0000)
to add 'CFMakeCollectable' semantics to a method.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70336 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Attr.h
include/clang/Parse/AttributeList.h
lib/Analysis/CFRefCount.cpp
lib/Frontend/PCHReaderDecl.cpp
lib/Frontend/PCHWriter.cpp
lib/Parse/AttributeList.cpp
lib/Sema/SemaDeclAttr.cpp
test/Analysis/retain-release-gc-only.m

index badab479113ad0403c8916fd34b91d913b20c061..b850958f1eaf3e9b3af42fb77c96d99052e77378 100644 (file)
@@ -59,11 +59,12 @@ public:
     NonNull,
     ObjCException,
     ObjCNSObject,
-    ObjCOwnershipCFRelease, // Clang/Checker-specific.
-    ObjCOwnershipCFRetain,  // Clang/Checker-specific.
-    ObjCOwnershipRelease,   // Clang/Checker-specific.
-    ObjCOwnershipRetain,    // Clang/Checker-specific.
-    ObjCOwnershipReturns,   // Clang/Checker-specific.
+    ObjCOwnershipCFRelease,       // Clang/Checker-specific.
+    ObjCOwnershipCFRetain,        // Clang/Checker-specific.
+    ObjCOwnershipMakeCollectable, // Clang/Checker-specific.
+    ObjCOwnershipRelease,         // Clang/Checker-specific.
+    ObjCOwnershipRetain,          // Clang/Checker-specific.
+    ObjCOwnershipReturns,         // Clang/Checker-specific.
     Overloadable, // Clang-specific
     Packed,
     Pure,
@@ -467,6 +468,7 @@ DEF_SIMPLE_ATTR(ObjCOwnershipCFRelease);
 DEF_SIMPLE_ATTR(ObjCOwnershipRelease);
 DEF_SIMPLE_ATTR(ObjCOwnershipCFRetain);
 DEF_SIMPLE_ATTR(ObjCOwnershipRetain);
+DEF_SIMPLE_ATTR(ObjCOwnershipMakeCollectable);
 DEF_SIMPLE_ATTR(ObjCOwnershipReturns);
 
 #undef DEF_SIMPLE_ATTR
index 4de27c1d99ddb0934fb724822cd508914d4dd830..15280431962e476401b9e42213e424124d6594be 100644 (file)
@@ -76,11 +76,12 @@ public:
     AT_nothrow,
     AT_nsobject,
     AT_objc_exception,
-    AT_objc_ownership_cfrelease, // Clang-specific.
-    AT_objc_ownership_cfretain,  // Clang-specific.
-    AT_objc_ownership_release,   // Clang-specific.
-    AT_objc_ownership_retain,    // Clang-specific.
-    AT_objc_ownership_returns,   // Clang-specific.
+    AT_objc_ownership_cfrelease,        // Clang-specific.
+    AT_objc_ownership_cfretain,         // Clang-specific.
+    AT_objc_ownership_make_collectable, // Clang-specific.
+    AT_objc_ownership_release,          // Clang-specific.
+    AT_objc_ownership_retain,           // Clang-specific.
+    AT_objc_ownership_returns,          // Clang-specific.
     AT_objc_gc,
     AT_overloadable,            // Clang-specific.
     AT_packed,
index 538f4f2722249824dad5e344f915b20b23f2f5e7..e1483d692d5114b2ba163b7a74d7597f35263100 100644 (file)
@@ -1121,6 +1121,10 @@ RetainSummaryManager::getMethodSummaryFromAnnotations(ObjCMethodDecl *MD) {
       ScratchArgs.push_back(std::make_pair(i, DecRef));
       hasArgEffect = true;
     }
+    else if ((*I)->getAttr<ObjCOwnershipMakeCollectableAttr>()) {
+      ScratchArgs.push_back(std::make_pair(i, MakeCollectable));
+      hasArgEffect = true;
+    }    
   }
   
   if (!hasRetEffect && !hasArgEffect)
index fc14a2623c40cd5636cb7fa3b64caa180b3012d6..22699e5716922185ec5c83ed5e2d0351d482ae12 100644 (file)
@@ -476,8 +476,9 @@ Attr *PCHReader::ReadAttributes() {
     SIMPLE_ATTR(ObjCException);
     SIMPLE_ATTR(ObjCNSObject);
     SIMPLE_ATTR(ObjCOwnershipCFRelease);
-    SIMPLE_ATTR(ObjCOwnershipRelease);
     SIMPLE_ATTR(ObjCOwnershipCFRetain);
+    SIMPLE_ATTR(ObjCOwnershipMakeCollectable);
+    SIMPLE_ATTR(ObjCOwnershipRelease);
     SIMPLE_ATTR(ObjCOwnershipRetain);
     SIMPLE_ATTR(ObjCOwnershipReturns);
     SIMPLE_ATTR(Overloadable);
index 04b552a488e764a13dded729d09977a9e2277289..8374e092a5377a3005f386504192643aaf92e7f7 100644 (file)
@@ -1545,8 +1545,9 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
     case Attr::ObjCException:
     case Attr::ObjCNSObject:
     case Attr::ObjCOwnershipCFRelease:
-    case Attr::ObjCOwnershipRelease:
     case Attr::ObjCOwnershipCFRetain:
+    case Attr::ObjCOwnershipMakeCollectable:
+    case Attr::ObjCOwnershipRelease:
     case Attr::ObjCOwnershipRetain:
     case Attr::ObjCOwnershipReturns:
     case Attr::Overloadable:
index cbc0031428ff793ca10637cbde61deb376298746..cbd230cc519f2c1c71dd7a62f3b48a301a0d7f2f 100644 (file)
@@ -152,6 +152,10 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
   case 24:
     if (!memcmp(Str, "objc_ownership_cfrelease", 24))
       return AT_objc_ownership_cfrelease;
+    break;      
+  case 31:
+    if (!memcmp(Str, "objc_ownership_make_collectable", 31))
+      return AT_objc_ownership_make_collectable;
     break;
   }  
   return UnknownAttribute;
index 09c627e42d1ea02194456caeb571a98411fc3184..9e550ba44f61d05e61d812d6dbcac0906564755e 100644 (file)
@@ -1539,14 +1539,16 @@ static void HandleObjCOwnershipParmAttr(Decl *d, const AttributeList &Attr,
       default:
         assert(0 && "invalid ownership attribute");
         return;
+      case AttributeList::AT_objc_ownership_cfrelease:
+        name = "objc_ownership_cfrelease"; break;
+      case AttributeList::AT_objc_ownership_cfretain:
+        name = "objc_ownership_cfretain"; break;
+      case AttributeList::AT_objc_ownership_make_collectable:
+        name = "objc_ownership_make_collectable"; break;
       case AttributeList::AT_objc_ownership_release:
         name = "objc_ownership_release"; break;
-      case AttributeList::AT_objc_ownership_cfrelease:
-        name = "objc_ownership_cfrelease"; break;        
       case AttributeList::AT_objc_ownership_retain:
         name = "objc_ownership_retain"; break;
-      case AttributeList::AT_objc_ownership_cfretain:
-        name = "objc_ownership_cfretain"; break;
     };
 
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << name
@@ -1558,14 +1560,16 @@ static void HandleObjCOwnershipParmAttr(Decl *d, const AttributeList &Attr,
     default:
       assert(0 && "invalid ownership attribute");
       return;
-    case AttributeList::AT_objc_ownership_release:
-      d->addAttr(::new (S.Context) ObjCOwnershipReleaseAttr());   return;
     case AttributeList::AT_objc_ownership_cfrelease:
       d->addAttr(::new (S.Context) ObjCOwnershipCFReleaseAttr()); return;      
-    case AttributeList::AT_objc_ownership_retain:
-      d->addAttr(::new (S.Context) ObjCOwnershipRetainAttr());   return;
     case AttributeList::AT_objc_ownership_cfretain:
       d->addAttr(::new (S.Context) ObjCOwnershipCFRetainAttr()); return;
+    case AttributeList::AT_objc_ownership_make_collectable:
+      d->addAttr(::new (S.Context) ObjCOwnershipMakeCollectableAttr()); return;
+    case AttributeList::AT_objc_ownership_release:
+      d->addAttr(::new (S.Context) ObjCOwnershipReleaseAttr());   return;
+    case AttributeList::AT_objc_ownership_retain:
+      d->addAttr(::new (S.Context) ObjCOwnershipRetainAttr());   return;
   }
 }
 
@@ -1607,10 +1611,11 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
   case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
 
   // Checker-specific.
+  case AttributeList::AT_objc_ownership_cfrelease:     
+  case AttributeList::AT_objc_ownership_cfretain:
+  case AttributeList::AT_objc_ownership_make_collectable:
   case AttributeList::AT_objc_ownership_release:
-  case AttributeList::AT_objc_ownership_cfrelease:
   case AttributeList::AT_objc_ownership_retain:
-  case AttributeList::AT_objc_ownership_cfretain:
     HandleObjCOwnershipParmAttr(D, Attr, S); break;
   case AttributeList::AT_objc_ownership_returns:
     HandleObjCOwnershipReturnsAttr(D, Attr, S); break;
index d4871f4de1f1d2a92fea0e8a7995f66f536cdb54..e008f4a795ab1cb9e331d38c7f240c75d9a86de1 100644 (file)
@@ -134,6 +134,7 @@ void f3() {
 - (void) myCFRetain:(id)__attribute__((objc_ownership_cfretain))obj;
 - (void) myRelease:(id)__attribute__((objc_ownership_release))obj;
 - (void) myCFRelease:(id)__attribute__((objc_ownership_cfrelease))obj;
+- (void) makeCollectable:(id)__attribute__((objc_ownership_make_collectable))obj;
 @end
 
 void test_attr_1(TestOwnershipAttr *X) {
@@ -181,3 +182,14 @@ void test_attr_5c(TestOwnershipAttr *X) {
   [X myCFRetain:str];
   [X myCFRelease:str];
 }
+
+void test_attr_6a(TestOwnershipAttr *X) {
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
+}
+
+void test_attr_6b(TestOwnershipAttr *X) {
+  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
+  [X makeCollectable:(id)A];
+}
+
+