diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaObjCProperty.cpp | 12 | ||||
-rw-r--r-- | test/SemaObjC/arc.m | 20 | ||||
-rw-r--r-- | test/SemaObjC/property-ns-returns-not-retained-attr.m | 21 |
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 |