aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-06-25 00:17:46 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-06-25 00:17:46 +0000
commit831fb9622581fc3b777848e6b097a0cb23d124de (patch)
tree4f39c6cba98cf0045b3748c0f0f13ff8934a14dd
parent88c1dfccf8c5d487408e3365c752ed24c867c7ce (diff)
objc-arc/mrc: Allow ns_returns_not_retained attribute on properties
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
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--lib/Sema/SemaDeclAttr.cpp2
-rw-r--r--lib/Sema/SemaObjCProperty.cpp12
-rw-r--r--test/SemaObjC/arc.m20
-rw-r--r--test/SemaObjC/property-ns-returns-not-retained-attr.m21
5 files changed, 57 insertions, 1 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index dd378fa191..1fc43c9dd0 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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">;
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 240c15a8e0..9302277e13 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -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
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 22f9b3e092..012e2569c3 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -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
diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m
index 3a548e084a..8d42d101dd 100644
--- a/test/SemaObjC/arc.m
+++ b/test/SemaObjC/arc.m
@@ -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
index 0000000000..187c93f3d3
--- /dev/null
+++ b/test/SemaObjC/property-ns-returns-not-retained-attr.m
@@ -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