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:
Fariborz Jahanian 2013-03-12 19:46:17 +00:00
parent f67ef79820
commit 9d25a48b41
4 changed files with 62 additions and 3 deletions

View File

@ -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", [

View File

@ -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">,

View File

@ -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;

View File

@ -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