forked from OSchip/llvm-project
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
This commit is contained in:
parent
e139dd4fe6
commit
059021a369
|
@ -365,7 +365,6 @@ def UnusedVariable : DiagGroup<"unused-variable",
|
||||||
def UnusedPropertyIvar : DiagGroup<"unused-property-ivar">;
|
def UnusedPropertyIvar : DiagGroup<"unused-property-ivar">;
|
||||||
def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">;
|
def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">;
|
||||||
def UserDefinedLiterals : DiagGroup<"user-defined-literals">;
|
def UserDefinedLiterals : DiagGroup<"user-defined-literals">;
|
||||||
def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">;
|
|
||||||
def Reorder : DiagGroup<"reorder">;
|
def Reorder : DiagGroup<"reorder">;
|
||||||
def UndeclaredSelector : DiagGroup<"undeclared-selector">;
|
def UndeclaredSelector : DiagGroup<"undeclared-selector">;
|
||||||
def ImplicitAtomic : DiagGroup<"implicit-atomic-properties">;
|
def ImplicitAtomic : DiagGroup<"implicit-atomic-properties">;
|
||||||
|
|
|
@ -822,9 +822,6 @@ def error_dynamic_property_ivar_decl : Error<
|
||||||
def error_duplicate_ivar_use : Error<
|
def error_duplicate_ivar_use : Error<
|
||||||
"synthesized properties %0 and %1 both claim instance variable %2">;
|
"synthesized properties %0 and %1 both claim instance variable %2">;
|
||||||
def error_property_implemented : Error<"property %0 is already implemented">;
|
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<ReadOnlySetterAttrs>, DefaultIgnore;
|
|
||||||
def warn_objc_missing_super_call : Warning<
|
def warn_objc_missing_super_call : Warning<
|
||||||
"method possibly missing a [super %0] call">,
|
"method possibly missing a [super %0] call">,
|
||||||
InGroup<ObjCMissingSuperCalls>;
|
InGroup<ObjCMissingSuperCalls>;
|
||||||
|
|
|
@ -321,21 +321,6 @@ static unsigned getOwnershipRule(unsigned attr) {
|
||||||
ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
|
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 *
|
ObjCPropertyDecl *
|
||||||
Sema::HandlePropertyInClassExtension(Scope *S,
|
Sema::HandlePropertyInClassExtension(Scope *S,
|
||||||
SourceLocation AtLoc,
|
SourceLocation AtLoc,
|
||||||
|
@ -2057,21 +2042,13 @@ void Sema::CheckObjCPropertyAttributes(Decl *PDecl,
|
||||||
QualType PropertyTy = PropertyDecl->getType();
|
QualType PropertyTy = PropertyDecl->getType();
|
||||||
unsigned PropertyOwnership = getOwnershipRule(Attributes);
|
unsigned PropertyOwnership = getOwnershipRule(Attributes);
|
||||||
|
|
||||||
if (Attributes & ObjCDeclSpec::DQ_PR_readonly) {
|
// 'readonly' property with no obvious lifetime.
|
||||||
if (getLangOpts().ObjCAutoRefCount &&
|
// its life time will be determined by its backing ivar.
|
||||||
PropertyTy->isObjCRetainableType() &&
|
if (getLangOpts().ObjCAutoRefCount &&
|
||||||
!PropertyOwnership) {
|
Attributes & ObjCDeclSpec::DQ_PR_readonly &&
|
||||||
// 'readonly' property with no obvious lifetime.
|
PropertyTy->isObjCRetainableType() &&
|
||||||
// its life time will be determined by its backing ivar.
|
!PropertyOwnership)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
else if (PropertyOwnership) {
|
|
||||||
if (!getSourceManager().isInSystemHeader(Loc))
|
|
||||||
Diag(Loc, diag::warn_objc_property_attr_mutually_exclusive)
|
|
||||||
<< "readonly" << NameOfOwnershipAttribute(Attributes);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for copy or retain on non-object types.
|
// Check for copy or retain on non-object types.
|
||||||
if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy |
|
if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy |
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// RUN: %clang_cc1 -fsyntax-only -verify -Weverything %s
|
// RUN: %clang_cc1 -fsyntax-only -verify -Weverything %s
|
||||||
|
// expected-no-diagnostics
|
||||||
// rdar://12103434
|
// rdar://12103434
|
||||||
|
|
||||||
@class NSString;
|
@class NSString;
|
||||||
|
@ -7,7 +8,7 @@
|
||||||
|
|
||||||
@interface MyClass : NSObject
|
@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
|
@end
|
||||||
|
|
||||||
|
|
|
@ -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
|
@protocol P0
|
||||||
@property(readonly,assign) id X; // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}}
|
@property(readonly,assign) id X;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@protocol P1
|
@protocol P1
|
||||||
@property(readonly,retain) id X; // expected-warning {{property attributes 'readonly' and 'retain' are mutually exclusive}}
|
@property(readonly,retain) id X;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@protocol P2
|
@protocol P2
|
||||||
@property(readonly,copy) id X; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}}
|
@property(readonly,copy) id X;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@protocol P3
|
@protocol P3
|
||||||
|
|
|
@ -8,20 +8,19 @@
|
||||||
|
|
||||||
@property (nonatomic, readonly) NSString* addingMemoryModel;
|
@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* none;
|
||||||
@property (readonly) NSString* none1;
|
@property (readonly) NSString* none1;
|
||||||
|
|
||||||
@property (assign, readonly) NSString* changeMemoryModel; // expected-note {{property declared here}} \
|
@property (assign, readonly) NSString* changeMemoryModel; // expected-note {{property declared here}}
|
||||||
// expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}}
|
|
||||||
|
|
||||||
@property (readonly) __weak id weak_prop;
|
@property (readonly) __weak id weak_prop;
|
||||||
@property (readonly) __weak id weak_prop1;
|
@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;
|
@property (readonly) NSString* readonlyProp;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
// RUN: %clang_cc1 -fsyntax-only -Weverything -verify %s
|
// RUN: %clang_cc1 -fsyntax-only -Weverything -verify %s
|
||||||
|
// expected-no-diagnostics
|
||||||
// rdar://11656982
|
// 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
|
(copy/retain/etc.). But, property declaration in primary class and protcols
|
||||||
are tentative as they may be overridden into a 'readwrite' property in class
|
are tentative as they may be overridden into a 'readwrite' property in class
|
||||||
extensions. Postpone diagnosing such warnings until the class implementation
|
extensions. So, do not issue any warning on 'readonly' and memory management
|
||||||
is seen.
|
attributes in a property.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@interface Super {
|
@interface Super {
|
||||||
|
@ -14,8 +15,8 @@
|
||||||
@class NSString;
|
@class NSString;
|
||||||
|
|
||||||
@interface MyClass : Super
|
@interface MyClass : Super
|
||||||
@property(nonatomic, copy, readonly) NSString *prop; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}}
|
@property(nonatomic, copy, readonly) NSString *prop;
|
||||||
@property(nonatomic, copy, readonly) id warnProp; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}}
|
@property(nonatomic, copy, readonly) id warnProp;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface MyClass ()
|
@interface MyClass ()
|
||||||
|
@ -29,8 +30,8 @@
|
||||||
|
|
||||||
|
|
||||||
@protocol P
|
@protocol P
|
||||||
@property(nonatomic, copy, readonly) NSString *prop; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}}
|
@property(nonatomic, copy, readonly) NSString *prop;
|
||||||
@property(nonatomic, copy, readonly) id warnProp; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}}
|
@property(nonatomic, copy, readonly) id warnProp;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface YourClass : Super <P>
|
@interface YourClass : Super <P>
|
||||||
|
|
Loading…
Reference in New Issue