]> granicus.if.org Git - clang/commitdiff
objc-arc/mrc: Allow ns_returns_not_retained attribute on properties
authorFariborz Jahanian <fjahanian@apple.com>
Sat, 25 Jun 2011 00:17:46 +0000 (00:17 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sat, 25 Jun 2011 00:17:46 +0000 (00:17 +0000)
to turn off warning on those properties which follow Cocoa naming
convention for retaining objects and yet they were not meant for
such purposes. Also, perform consistancy checking for declared
getters of such methods. // rdar://9636091

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaObjCProperty.cpp
test/SemaObjC/arc.m
test/SemaObjC/property-ns-returns-not-retained-attr.m [new file with mode: 0644]

index dd378fa1919ca5ca2a1b3aaf1ec9ab625c8faadb..1fc43c9dd05c05ea586032b030d5b031e4096af8 100644 (file)
@@ -441,6 +441,9 @@ def warn_atomic_property_rule : Warning<
 def warn_ownin_getter_rule : Warning<
   "property's synthesized getter follows Cocoa naming"
   " convention for returning 'owned' objects">;
+def warn_property_getter_owning_mismatch : Warning<
+  "property declared as returning non-retained objects"
+  "; getter returning retained objects">;
 def err_ownin_getter_rule : Error<
   "property's synthesized getter follows Cocoa naming"
   " convention for returning 'owned' objects">;
index 240c15a8e06428edae9fcb68d757bebef4f585f3..9302277e13bd9d38ff645b078c065c66cd1019d4 100644 (file)
@@ -2716,6 +2716,8 @@ static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &attr,
 
   if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
     returnType = MD->getResultType();
+  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d))
+    returnType = PD->getType();
   else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(d) &&
            (attr.getKind() == AttributeList::AT_ns_returns_retained))
     return; // ignore: was handled as a type attribute
index 22f9b3e092be8bb4d73022b09541dcc501d994f3..012e2569c33380718a69a3dac66cea01c4928272 100644 (file)
@@ -737,6 +737,12 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
         PIDecl->setGetterCXXConstructor(ResExpr);
       }
     }
+    if (property->hasAttr<NSReturnsNotRetainedAttr>() &&
+        !getterMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
+      Diag(getterMethod->getLocation(), 
+           diag::warn_property_getter_owning_mismatch);
+      Diag(property->getLocation(), diag::note_property_declare);
+    }
   }
   if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
     setterMethod->createImplicitParams(Context, IDecl);
@@ -1369,7 +1375,8 @@ void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D
       continue;
     
     const ObjCPropertyDecl *PD = PID->getPropertyDecl();
-    if (PD && !D->getInstanceMethod(PD->getGetterName())) {
+    if (PD && !PD->hasAttr<NSReturnsNotRetainedAttr>() &&
+        !D->getInstanceMethod(PD->getGetterName())) {
       ObjCMethodDecl *method = PD->getGetterMethodDecl();
       if (!method)
         continue;
@@ -1465,6 +1472,9 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
     // and the real context should be the same.
     if (lexicalDC)
       GetterMethod->setLexicalDeclContext(lexicalDC);
+    if (property->hasAttr<NSReturnsNotRetainedAttr>())
+      GetterMethod->addAttr(
+        ::new (Context) NSReturnsNotRetainedAttr(Loc, Context));
   } else
     // A user declared getter will be synthesize when @synthesize of
     // the property with the same name is seen in the @implementation
index 3a548e084a59fc6cca131212171850af01526f77..8d42d101ddac646ce1836673df5e50fdbbc3af71 100644 (file)
@@ -572,3 +572,23 @@ int Test33(id someid) {
   return (int)someid;
 }
 
+// rdar://9636091
+@interface I34
+@property (nonatomic, retain) id newName __attribute__((ns_returns_not_retained)) ;
+
+@property (nonatomic, retain) id newName1 __attribute__((ns_returns_not_retained)) ;
+- (id) newName1 __attribute__((ns_returns_not_retained));
+
+@property (nonatomic, retain) id newName2 __attribute__((ns_returns_not_retained)); // expected-note {{roperty declared here}}
+- (id) newName2;   // expected-warning {{property declared as returning non-retained objects; getter returning retained objects}}
+@end
+
+@implementation I34
+@synthesize newName;
+
+@synthesize newName1;
+- (id) newName1 { return 0; }
+
+@synthesize newName2;
+@end
+
diff --git a/test/SemaObjC/property-ns-returns-not-retained-attr.m b/test/SemaObjC/property-ns-returns-not-retained-attr.m
new file mode 100644 (file)
index 0000000..187c93f
--- /dev/null
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-nonfragile-abi -fsyntax-only -verify %s
+// rdar://9636091
+
+@interface I
+@property (nonatomic, retain) id newName __attribute__((ns_returns_not_retained)) ;
+
+@property (nonatomic, retain) id newName1 __attribute__((ns_returns_not_retained)) ;
+- (id) newName1 __attribute__((ns_returns_not_retained));
+
+@property (nonatomic, retain) id newName2 __attribute__((ns_returns_not_retained)); // expected-note {{roperty declared here}}
+- (id) newName2;   // expected-warning {{property declared as returning non-retained objects; getter returning retained objects}}
+@end
+
+@implementation I
+@synthesize newName;
+
+@synthesize newName1;
+- (id) newName1 { return 0; }
+
+@synthesize newName2;
+@end