From 6114a3c9baf29b3db1e0853a829ae1278285aef4 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 12 Mar 2013 19:46:17 +0000 Subject: [PATCH] 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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176889 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticGroups.td | 2 ++ include/clang/Basic/DiagnosticSemaKinds.td | 9 +++++++ lib/Sema/SemaObjCProperty.cpp | 24 ++++++++++++++--- test/SemaObjC/default-synthesize-3.m | 30 ++++++++++++++++++++++ 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 61d5242803..a610f62c51 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -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", [ diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index c7cd205b54..87f95aca4b 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -666,6 +666,15 @@ def warn_auto_synthesizing_protocol_property :Warning< "auto property synthesis will not synthesize property" " declared in a protocol">, InGroup>; +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; +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; def warn_autosynthesis_property_ivar_match :Warning< "autosynthesized property %0 will use %select{|synthesized}1 instance variable " "%2, not existing instance variable %3">, diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index e046faa04d..2195541cd7 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -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; diff --git a/test/SemaObjC/default-synthesize-3.m b/test/SemaObjC/default-synthesize-3.m index 606ece33af..06741e119e 100644 --- a/test/SemaObjC/default-synthesize-3.m +++ b/test/SemaObjC/default-synthesize-3.m @@ -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 +@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 -- 2.40.0