forked from OSchip/llvm-project
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 llvm-svn: 133849
This commit is contained in:
parent
3c7a726a6d
commit
f4105f5cfe
|
@ -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">;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue