]> granicus.if.org Git - clang/commitdiff
Objective-C: Issue warning in couple of obscure cases
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 12 Mar 2013 19:46:17 +0000 (19:46 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 12 Mar 2013 19:46:17 +0000 (19:46 +0000)
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
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaObjCProperty.cpp
test/SemaObjC/default-synthesize-3.m

index 61d5242803d01f01662408fd77d7b3b9aaab9eaf..a610f62c51326f5dd367a335ffa3b005257d5fac 100644 (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", [
index c7cd205b548e935ed96812dfd399b1e7f5cb34f9..87f95aca4ba04c20e23070658e5b9ed1c3cf2fca 100644 (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">,
index e046faa04d0ae722c32aee34b507e073f904b1bb..2195541cd74198ad1598b491c95d2d9a605eb86c 100644 (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;
index 606ece33af8d48f0725236a42a595b383bf51a64..06741e119e5ba5ec1e4356141b8fe648e47b1a81 100644 (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