From 059021a36937788d4951b74a663f0a0621aa85bc Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 13 Dec 2013 18:19:59 +0000 Subject: [PATCH] Objective-C. Do not issue warning when 'readonly' property declaration has a memory management attribute (retain, copy, etc.). Sich properties are usually overridden to become 'readwrite' via a class extension (which require the memory management attribute specified). In the absence of class extension override, memory management attribute is needed to produce correct Code Gen. for the property getter in any case and this warning becomes confusing to user. // rdar://15641300 llvm-svn: 197251 --- clang/include/clang/Basic/DiagnosticGroups.td | 1 - .../clang/Basic/DiagnosticSemaKinds.td | 3 -- clang/lib/Sema/SemaObjCProperty.cpp | 37 ++++--------------- .../overriding-property-in-class-extension.m | 3 +- clang/test/SemaObjC/property-12.m | 8 ++-- .../SemaObjC/property-in-class-extension-1.m | 9 ++--- clang/test/SemaObjC/tentative-property-decl.m | 15 ++++---- 7 files changed, 25 insertions(+), 51 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 7f1c5dc9c16b..14b01040de5a 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -365,7 +365,6 @@ def UnusedVariable : DiagGroup<"unused-variable", def UnusedPropertyIvar : DiagGroup<"unused-property-ivar">; def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">; def UserDefinedLiterals : DiagGroup<"user-defined-literals">; -def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">; def Reorder : DiagGroup<"reorder">; def UndeclaredSelector : DiagGroup<"undeclared-selector">; def ImplicitAtomic : DiagGroup<"implicit-atomic-properties">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index fdea0a3c94a0..3274064fece6 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -822,9 +822,6 @@ def error_dynamic_property_ivar_decl : Error< def error_duplicate_ivar_use : Error< "synthesized properties %0 and %1 both claim instance variable %2">; def error_property_implemented : Error<"property %0 is already implemented">; -def warn_objc_property_attr_mutually_exclusive : Warning< - "property attributes '%0' and '%1' are mutually exclusive">, - InGroup, DefaultIgnore; def warn_objc_missing_super_call : Warning< "method possibly missing a [super %0] call">, InGroup; diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index 78e774b39ffc..93791d7667ce 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -321,21 +321,6 @@ static unsigned getOwnershipRule(unsigned attr) { ObjCPropertyDecl::OBJC_PR_unsafe_unretained); } -static const char *NameOfOwnershipAttribute(unsigned attr) { - if (attr & ObjCPropertyDecl::OBJC_PR_assign) - return "assign"; - if (attr & ObjCPropertyDecl::OBJC_PR_retain ) - return "retain"; - if (attr & ObjCPropertyDecl::OBJC_PR_copy) - return "copy"; - if (attr & ObjCPropertyDecl::OBJC_PR_weak) - return "weak"; - if (attr & ObjCPropertyDecl::OBJC_PR_strong) - return "strong"; - assert(attr & ObjCPropertyDecl::OBJC_PR_unsafe_unretained); - return "unsafe_unretained"; -} - ObjCPropertyDecl * Sema::HandlePropertyInClassExtension(Scope *S, SourceLocation AtLoc, @@ -2057,21 +2042,13 @@ void Sema::CheckObjCPropertyAttributes(Decl *PDecl, QualType PropertyTy = PropertyDecl->getType(); unsigned PropertyOwnership = getOwnershipRule(Attributes); - if (Attributes & ObjCDeclSpec::DQ_PR_readonly) { - if (getLangOpts().ObjCAutoRefCount && - PropertyTy->isObjCRetainableType() && - !PropertyOwnership) { - // 'readonly' property with no obvious lifetime. - // its life time will be determined by its backing ivar. - return; - } - else if (PropertyOwnership) { - if (!getSourceManager().isInSystemHeader(Loc)) - Diag(Loc, diag::warn_objc_property_attr_mutually_exclusive) - << "readonly" << NameOfOwnershipAttribute(Attributes); - return; - } - } + // 'readonly' property with no obvious lifetime. + // its life time will be determined by its backing ivar. + if (getLangOpts().ObjCAutoRefCount && + Attributes & ObjCDeclSpec::DQ_PR_readonly && + PropertyTy->isObjCRetainableType() && + !PropertyOwnership) + return; // Check for copy or retain on non-object types. if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy | diff --git a/clang/test/SemaObjC/overriding-property-in-class-extension.m b/clang/test/SemaObjC/overriding-property-in-class-extension.m index 8c0e1b98a572..77efd556928c 100644 --- a/clang/test/SemaObjC/overriding-property-in-class-extension.m +++ b/clang/test/SemaObjC/overriding-property-in-class-extension.m @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Weverything %s +// expected-no-diagnostics // rdar://12103434 @class NSString; @@ -7,7 +8,7 @@ @interface MyClass : NSObject -@property (nonatomic, copy, readonly) NSString* name; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} +@property (nonatomic, copy, readonly) NSString* name; @end diff --git a/clang/test/SemaObjC/property-12.m b/clang/test/SemaObjC/property-12.m index c4a755555629..5fc311aa90ad 100644 --- a/clang/test/SemaObjC/property-12.m +++ b/clang/test/SemaObjC/property-12.m @@ -1,15 +1,15 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -Wreadonly-setter-attrs -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s @protocol P0 -@property(readonly,assign) id X; // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}} +@property(readonly,assign) id X; @end @protocol P1 -@property(readonly,retain) id X; // expected-warning {{property attributes 'readonly' and 'retain' are mutually exclusive}} +@property(readonly,retain) id X; @end @protocol P2 -@property(readonly,copy) id X; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} +@property(readonly,copy) id X; @end @protocol P3 diff --git a/clang/test/SemaObjC/property-in-class-extension-1.m b/clang/test/SemaObjC/property-in-class-extension-1.m index 51837fd212ca..ab461ef6c191 100644 --- a/clang/test/SemaObjC/property-in-class-extension-1.m +++ b/clang/test/SemaObjC/property-in-class-extension-1.m @@ -8,20 +8,19 @@ @property (nonatomic, readonly) NSString* addingMemoryModel; -@property (nonatomic, copy, readonly) NSString* matchingMemoryModel; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} +@property (nonatomic, copy, readonly) NSString* matchingMemoryModel; -@property (nonatomic, retain, readonly) NSString* addingNoNewMemoryModel; // expected-warning {{property attributes 'readonly' and 'retain' are mutually exclusive}} +@property (nonatomic, retain, readonly) NSString* addingNoNewMemoryModel; @property (readonly) NSString* none; @property (readonly) NSString* none1; -@property (assign, readonly) NSString* changeMemoryModel; // expected-note {{property declared here}} \ - // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}} +@property (assign, readonly) NSString* changeMemoryModel; // expected-note {{property declared here}} @property (readonly) __weak id weak_prop; @property (readonly) __weak id weak_prop1; -@property (assign, readonly) NSString* assignProperty; // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}} +@property (assign, readonly) NSString* assignProperty; @property (readonly) NSString* readonlyProp; diff --git a/clang/test/SemaObjC/tentative-property-decl.m b/clang/test/SemaObjC/tentative-property-decl.m index aa7df5294a8a..a9649b644c31 100644 --- a/clang/test/SemaObjC/tentative-property-decl.m +++ b/clang/test/SemaObjC/tentative-property-decl.m @@ -1,10 +1,11 @@ // RUN: %clang_cc1 -fsyntax-only -Weverything -verify %s +// expected-no-diagnostics // rdar://11656982 -/** Normally, a property cannot be both 'readonly' and having a "write" attribute +/** A property may not be both 'readonly' and having a memory management attribute (copy/retain/etc.). But, property declaration in primary class and protcols are tentative as they may be overridden into a 'readwrite' property in class - extensions. Postpone diagnosing such warnings until the class implementation - is seen. + extensions. So, do not issue any warning on 'readonly' and memory management + attributes in a property. */ @interface Super { @@ -14,8 +15,8 @@ @class NSString; @interface MyClass : Super -@property(nonatomic, copy, readonly) NSString *prop; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} -@property(nonatomic, copy, readonly) id warnProp; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} +@property(nonatomic, copy, readonly) NSString *prop; +@property(nonatomic, copy, readonly) id warnProp; @end @interface MyClass () @@ -29,8 +30,8 @@ @protocol P -@property(nonatomic, copy, readonly) NSString *prop; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} -@property(nonatomic, copy, readonly) id warnProp; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} +@property(nonatomic, copy, readonly) NSString *prop; +@property(nonatomic, copy, readonly) id warnProp; @end @interface YourClass : Super