]> granicus.if.org Git - clang/commitdiff
Add new checker-specific attribute 'objc_ownership_returns'. This isn't hooked
authorTed Kremenek <kremenek@apple.com>
Fri, 24 Apr 2009 23:09:54 +0000 (23:09 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 24 Apr 2009 23:09:54 +0000 (23:09 +0000)
up to the checker yet, but essentially it allows a user to specify that an
Objective-C method or C function returns an owned an Objective-C object.

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

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

index 085b51c5ca7d23e90855e993f9d20d4937d61eec..93a9edb8077bf85463a78827be498338be9db62f 100644 (file)
@@ -51,6 +51,7 @@ public:
     NonNull,
     ObjCException,
     ObjCNSObject,
+    ObjCOwnershipReturns, // Clang/Checker-specific.
     Overloadable, // Clang-specific
     Packed,
     Pure,
@@ -587,6 +588,21 @@ public:
   static bool classof(const Attr *A) { return A->getKind() == Regparm; }
   static bool classof(const RegparmAttr *A) { return true; }
 };
+  
+  
+#define DEF_SIMPLE_ATTR(ATTR)\
+class ATTR##Attr : public Attr {\
+public:\
+  ATTR##Attr() : Attr(ATTR) {}\
+  static bool classof(const Attr *A) { return A->getKind() == ATTR; }\
+  static bool classof(const ATTR##Attr *A) { return true; }\
+};
+
+// Checker-specific attributes.
+DEF_SIMPLE_ATTR(ObjCOwnershipReturns)
+
+#undef DEF_SIMPLE_ATTR
+  
 }  // end namespace clang
 
 #endif
index 1e94a71a647cba2f4b3b54adb7a4f7ddf6d4b031..9712cc896edac593aab58d52ff73f9b97db207f8 100644 (file)
@@ -75,8 +75,9 @@ public:
     AT_nothrow,
     AT_nsobject,
     AT_objc_exception,
+    AT_objc_ownership_returns, // Clang-specific.
     AT_objc_gc,
-    AT_overloadable,      // Clang-specific
+    AT_overloadable,      // Clang-specific.
     AT_packed,
     AT_pure,
     AT_regparm,
index 2dfb7e0a0a0c60977a91c7df44f8d9056ecde77d..bbe92a0329ef2bc48818e728cfcf9af32ccee41e 100644 (file)
@@ -3045,6 +3045,7 @@ Attr *PCHReader::ReadAttributes() {
 
     SIMPLE_ATTR(ObjCException);
     SIMPLE_ATTR(ObjCNSObject);
+    SIMPLE_ATTR(ObjCOwnershipReturns);
     SIMPLE_ATTR(Overloadable);
     UNSIGNED_ATTR(Packed);
     SIMPLE_ATTR(Pure);
index 782244c60ed49f9ec615782d15c7e4c257523f25..4d2f4092ef721f371e350b5e7feee67c4f440ced 100644 (file)
@@ -2181,6 +2181,7 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
 
     case Attr::ObjCException:
     case Attr::ObjCNSObject:
+    case Attr::ObjCOwnershipReturns:
     case Attr::Overloadable:
       break;
 
index 5797a1540804a2aee709424b35f4882f0ffde3bc..33715899c5ccb2d4cd2d733a6b961fe4016e8de4 100644 (file)
@@ -133,6 +133,10 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
   case 18:
     if (!memcmp(Str, "warn_unused_result", 18)) return AT_warn_unused_result;
     break;
+  case 22:
+    if (!memcmp(Str, "objc_ownership_returns", 22))
+      return AT_objc_ownership_returns;
+    break;
   }
   return UnknownAttribute;
 }
index d05b99ac365c357fbe01f158784aafc4e7ec019b..5a99fdccd16da6835bba27167b5752c75bfe90e3 100644 (file)
@@ -1517,6 +1517,22 @@ static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
 }
 
+//===----------------------------------------------------------------------===//
+// Checker-specific attribute handlers.
+//===----------------------------------------------------------------------===//
+
+static void HandleObjCOwnershipReturnsAttr(Decl *d, const AttributeList &Attr,
+                                           Sema &S) {
+
+  if (!isa<ObjCMethodDecl>(d) && !isa<FunctionDecl>(d)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
+      "objc_ownership_returns" << 3 /* function or method */;
+    return;
+  }
+  
+  d->addAttr(::new (S.Context) ObjCOwnershipReturnsAttr());
+}
+
 //===----------------------------------------------------------------------===//
 // Top Level Sema Entry Points
 //===----------------------------------------------------------------------===//
@@ -1553,6 +1569,11 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
   case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
   case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
   case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
+
+  // Checker-specific.
+  case AttributeList::AT_objc_ownership_returns:
+    HandleObjCOwnershipReturnsAttr(D, Attr, S); break;
+
   case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
   case AttributeList::AT_section:     HandleSectionAttr   (D, Attr, S); break;
   case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
index 012e340f563e80c3819eef968dfb50ff6575a7bc..b8e819012baad18507e79dfbdfa395bed9fed19e 100644 (file)
@@ -405,3 +405,15 @@ void rdar6704930(unsigned char *s, unsigned int length) {
   }
 }
 
+//===----------------------------------------------------------------------===//
+// Tests of ownership attributes.
+//===----------------------------------------------------------------------===//
+
+@interface TestOwnershipAttr : NSObject
+- (NSString*) returnsAnOwnedString __attribute__((objc_ownership_returns));
+@end
+
+void test_attr_1(TestOwnershipAttr *X) {
+  NSString *str = [X returnsAnOwnedString];
+}
+