Objective-C: Issue warning in couple of obscure cases
when property autosynthesis does not synthesize a property. When property is declared 'readonly' in a super class and is redeclared 'readwrite' in a subclass. When a property autosynthesis causes it to share 'ivar' with another property. // rdar://13388503 llvm-svn: 176889
This commit is contained in:
parent
f67ef79820
commit
9d25a48b41
|
@ -490,6 +490,8 @@ def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">;
|
|||
|
||||
def ObjCProtocolMethodImpl : DiagGroup<"objc-protocol-method-implementation">;
|
||||
|
||||
def ObjCNoPropertyAuthoSynthesis : DiagGroup<"objc-property-synthesis">;
|
||||
|
||||
// ObjC API warning groups.
|
||||
def ObjCRedundantLiteralUse : DiagGroup<"objc-redundant-literal-use">;
|
||||
def ObjCRedundantAPIUse : DiagGroup<"objc-redundant-api-use", [
|
||||
|
|
|
@ -666,6 +666,15 @@ def warn_auto_synthesizing_protocol_property :Warning<
|
|||
"auto property synthesis will not synthesize property"
|
||||
" declared in a protocol">,
|
||||
InGroup<DiagGroup<"objc-protocol-property-synthesis">>;
|
||||
def warn_no_autosynthesis_shared_ivar_property : Warning <
|
||||
"auto property synthesis will not synthesize property "
|
||||
"'%0' because it cannot share an ivar with another synthesized property">,
|
||||
InGroup<ObjCNoPropertyAuthoSynthesis>;
|
||||
def warn_no_autosynthesis_property : Warning<
|
||||
"auto property synthesis will not synthesize property "
|
||||
"'%0' because it is 'readwrite' but it will be synthesized 'readonly' "
|
||||
"via another property">,
|
||||
InGroup<ObjCNoPropertyAuthoSynthesis>;
|
||||
def warn_autosynthesis_property_ivar_match :Warning<
|
||||
"autosynthesized property %0 will use %select{|synthesized}1 instance variable "
|
||||
"%2, not existing instance variable %3">,
|
||||
|
|
|
@ -1585,13 +1585,31 @@ void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl* IMPDecl,
|
|||
for (unsigned i = 0, e = PropertyOrder.size(); i != e; i++) {
|
||||
ObjCPropertyDecl *Prop = PropertyOrder[i];
|
||||
// If property to be implemented in the super class, ignore.
|
||||
if (SuperPropMap[Prop->getIdentifier()])
|
||||
if (SuperPropMap[Prop->getIdentifier()]) {
|
||||
ObjCPropertyDecl *PropInSuperClass = SuperPropMap[Prop->getIdentifier()];
|
||||
if ((Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite) &&
|
||||
(PropInSuperClass->getPropertyAttributes() &
|
||||
ObjCPropertyDecl::OBJC_PR_readonly)) {
|
||||
Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property)
|
||||
<< Prop->getIdentifier()->getName();
|
||||
Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Is there a matching property synthesize/dynamic?
|
||||
if (Prop->isInvalidDecl() ||
|
||||
Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
|
||||
IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier()))
|
||||
Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional)
|
||||
continue;
|
||||
if (ObjCPropertyImplDecl *PID =
|
||||
IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) {
|
||||
if (PID->getPropertyDecl() != Prop) {
|
||||
Diag(Prop->getLocation(), diag::warn_no_autosynthesis_shared_ivar_property)
|
||||
<< Prop->getIdentifier()->getName();
|
||||
if (!PID->getLocation().isInvalid())
|
||||
Diag(PID->getLocation(), diag::note_property_synthesize);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Property may have been synthesized by user.
|
||||
if (IMPDecl->FindPropertyImplDecl(Prop->getIdentifier()))
|
||||
continue;
|
||||
|
|
|
@ -39,3 +39,33 @@ __attribute ((objc_requires_property_definitions))
|
|||
|
||||
__attribute ((objc_requires_property_definitions)) // expected-error {{objc_requires_property_definitions attribute may only be specified on a class}}
|
||||
@protocol P @end
|
||||
|
||||
// rdar://13388503
|
||||
@interface NSObject @end
|
||||
@protocol Foo
|
||||
@property (readonly) char isFoo; // expected-note {{property declared here}}
|
||||
@end
|
||||
|
||||
@interface Bar : NSObject <Foo>
|
||||
@end
|
||||
|
||||
@implementation Bar
|
||||
- (char)isFoo {
|
||||
return 0;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface Baz : Bar
|
||||
@end
|
||||
|
||||
@interface Baz ()
|
||||
@property (readwrite) char isFoo; // expected-warning {{auto property synthesis will not synthesize property 'isFoo' because it is 'readwrite' but it will be synthesized 'readonly' via another property}}
|
||||
@property char Property1; // expected-warning {{auto property synthesis will not synthesize property 'Property1' because it cannot share an ivar with another synthesized property}}
|
||||
@property char Property2;
|
||||
@end
|
||||
|
||||
@implementation Baz {
|
||||
char _isFoo;
|
||||
}
|
||||
@synthesize Property2 = Property1; // expected-note {{property synthesized here}}
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue