Objective-C. Issue more warning diagnostic when certain
authorFariborz Jahanian <fjahanian@apple.com>
Sat, 26 Jul 2014 20:52:26 +0000 (20:52 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sat, 26 Jul 2014 20:52:26 +0000 (20:52 +0000)
properties are not synthesized in property auto-synthesis,
as it can potentiall lead to runtime errors.
rdar://17774815

llvm-svn: 214032

clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaObjCProperty.cpp
clang/test/Analysis/objc_invalidation.m
clang/test/SemaObjC/attr-deprecated.m
clang/test/SemaObjC/default-synthesize-1.m
clang/test/SemaObjC/default-synthesize-3.m
clang/test/SemaObjC/default-synthesize.m
clang/test/SemaObjC/protocols-suppress-conformance.m
clang/test/SemaObjC/super-property-notation.m

index 366f6d2..3a83652 100644 (file)
@@ -783,6 +783,10 @@ def warn_no_autosynthesis_property : Warning<
   "%0 because it is 'readwrite' but it will be synthesized 'readonly' "
   "via another property">,
   InGroup<ObjCNoPropertyAutoSynthesis>;
+def warn_autosynthesis_property_in_superclass : Warning<
+  "auto property synthesis will not synthesize property "
+  "%0 because it will be synthesize by its super class">,
+  InGroup<ObjCNoPropertyAutoSynthesis>;
 def warn_autosynthesis_property_ivar_match :Warning<
   "autosynthesized property %0 will use %select{|synthesized}1 instance variable "
   "%2, not existing instance variable %3">,
index 8eb806b..0032294 100644 (file)
@@ -1555,20 +1555,23 @@ void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl* IMPDecl,
            ObjCPropertyDecl::OBJC_PR_readonly) &&
           !IMPDecl->getInstanceMethod(Prop->getSetterName()) &&
           !IDecl->HasUserDeclaredSetterMethod(Prop)) {
-            Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property)
-              << Prop->getIdentifier();
-            Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
+        Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property)
+          << Prop->getIdentifier();
+        Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
+      }
+      else {
+        Diag(Prop->getLocation(), diag::warn_autosynthesis_property_in_superclass)
+          << Prop->getIdentifier();
+        Diag(IMPDecl->getLocation(), diag::note_while_in_implementation);
       }
       continue;
     }
     if (ObjCPropertyImplDecl *PID =
         IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) {
-      if (PID->getPropertyDecl() != Prop) {
-        Diag(Prop->getLocation(), diag::warn_no_autosynthesis_shared_ivar_property)
-          << Prop->getIdentifier();
-        if (!PID->getLocation().isInvalid())
-          Diag(PID->getLocation(), diag::note_property_synthesize);
-      }
+      Diag(Prop->getLocation(), diag::warn_no_autosynthesis_shared_ivar_property)
+        << Prop->getIdentifier();
+      if (!PID->getLocation().isInvalid())
+        Diag(PID->getLocation(), diag::note_property_synthesize);
       continue;
     }
     if (ObjCProtocolDecl *Proto =
index cd66444..9ac9828 100644 (file)
@@ -199,7 +199,7 @@ extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1,
 // synthesized in the parent, let the parent invalidate it.
 
 @protocol IDEBuildable <NSObject>
-@property (readonly, strong) id <Invalidation2> ObjB;
+@property (readonly, strong) id <Invalidation2> ObjB; // expected-warning {{auto property synthesis will not synthesize property 'ObjB'}}
 @end
 
 @interface Parent : NSObject <IDEBuildable, Invalidation2> {
@@ -231,7 +231,7 @@ extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1,
 }
 @end
 
-@implementation Child
+@implementation Child // expected-note {{detected while default synthesizing properties in class implementation}}
 - (void)invalidate{ 
   // no-warning
 } 
index ca30d0a..f18f99f 100644 (file)
@@ -201,14 +201,14 @@ expected-note {{'setObject:' has been explicitly marked deprecated here}}
 @end
 
 @interface TestDerived : TestBase
-@property (nonatomic, strong) id object;
+@property (nonatomic, strong) id object; //expected-warning {{auto property synthesis will not synthesize property 'object' because it will be synthesize by its super class}}
 @end
 
 @interface TestUse @end
 
 @implementation TestBase @end
 
-@implementation TestDerived @end
+@implementation TestDerived @end // expected-note {{detected while default synthesizing properties in class implementation}}
 
 @implementation TestUse
 
index f9f2e72..31dd669 100644 (file)
                              // expected-note {{detected while default synthesizing properties in class implementation}}
 @synthesize x; // expected-error {{cannot synthesize property 'x' with incomplete type 'enum A'}}
 @end
+
+// rdar://17774815
+@interface ZXParsedResult
+@property (nonatomic, copy, readonly) NSString *description;
+@end
+
+@interface ZXCalendarParsedResult : ZXParsedResult
+
+@property (nonatomic, copy, readonly) NSString *description; // expected-warning {{auto property synthesis will not synthesize property 'description' because it will be synthesize by its super class}}
+
+@end
+
+@implementation ZXCalendarParsedResult // expected-note {{detected while default synthesizing properties in class implementation}}
+- (NSString *) Meth {
+    return _description; // expected-error {{use of undeclared identifier '_description'}}
+}
+@end
index c915974..879335e 100644 (file)
@@ -66,10 +66,10 @@ __attribute ((objc_requires_property_definitions)) // expected-error {{'objc_req
 @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;
-@property (readwrite) char isNotFree;
+@property (readwrite) char isNotFree; // expected-warning {{auto property synthesis will not synthesize property 'isNotFree'}}
 @end
 
-@implementation Baz {
+@implementation Baz { // expected-note {{detected while default synthesizing properties in class implementation}}
     char _isFoo;
     char _isNotFree;
 }
@@ -104,12 +104,12 @@ __attribute ((objc_requires_property_definitions)) // expected-error {{'objc_req
 @end
 
 @interface S : B<P1>
-@property (assign,readwrite) id prop;
-@property (assign,readwrite) id prop1;
-@property (assign,readwrite) id prop2;
+@property (assign,readwrite) id prop; // expected-warning {{auto property synthesis will not synthesize property 'prop'}}
+@property (assign,readwrite) id prop1; // expected-warning {{auto property synthesis will not synthesize property 'prop1'}}
+@property (assign,readwrite) id prop2; // expected-warning {{auto property synthesis will not synthesize property 'prop2'}}
 @end
 
-@implementation S
+@implementation S // expected-note 3 {{detected while default synthesizing properties in class implementation}}
 @end
 
 // rdar://14085456
index 9356b9f..a3abe2e 100644 (file)
@@ -88,7 +88,7 @@
 @end
 
 @protocol TopProtocol
-  @property (readonly) id myString;
+  @property (readonly) id myString; // expected-warning {{auto property synthesis will not synthesize property 'myString' because it will be synthesize by its super class}}
 @end
 
 @interface TopClass <TopProtocol> 
 }
 @end
 
-@interface SubClass : TopClass <TopProtocol> 
+@interface SubClass : TopClass <TopProtocol>
 @end
 
-@implementation SubClass @end 
+@implementation SubClass @end  // expected-note {{detected while default synthesizing properties in class implementation}}
 
 // rdar://7920807
 @interface C @end
index 299e44e..dffa6c2 100644 (file)
@@ -5,7 +5,8 @@
 __attribute__((objc_protocol_requires_explicit_implementation))
 @protocol Protocol
 - (void) theBestOfTimes; // expected-note {{method 'theBestOfTimes' declared here}}
-@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}}
+@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}} \
+                                        // expected-warning 2 {{auto property synthesis will not synthesize property 'theWorstOfTimes'}}
 @end
 
 // In this example, ClassA adopts the protocol.  We won't
@@ -20,7 +21,8 @@ __attribute__((objc_protocol_requires_explicit_implementation))
 @interface ClassB : ClassA <Protocol>
 @end
 
-@implementation ClassB // expected-warning {{property 'theWorstOfTimes' requires method 'theWorstOfTimes' to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation}}
+@implementation ClassB // expected-warning {{property 'theWorstOfTimes' requires method 'theWorstOfTimes' to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation}} \
+                     // expected-note {{detected while default synthesizing properties in class implementation}}
 @end
 
 @interface ClassB_Good : ClassA <Protocol>
@@ -32,7 +34,7 @@ __attribute__((objc_protocol_requires_explicit_implementation))
 @end
 
 @interface ClassB_AlsoGood : ClassA <Protocol>
-@property (readonly) id theWorstOfTimes;
+@property (readonly) id theWorstOfTimes; // expected-warning {{auto property synthesis will not synthesize property 'theWorstOfTimes' because it will be synthesize by its super class}}
 @end
 
 // Default synthesis acts as if @dynamic
@@ -40,7 +42,7 @@ __attribute__((objc_protocol_requires_explicit_implementation))
 // it is declared in ClassA.  This is okay, since
 // the author of ClassB_AlsoGood needs explicitly
 // write @property in the @interface.
-@implementation ClassB_AlsoGood // no-warning
+@implementation ClassB_AlsoGood  // expected-note 2 {{detected while default synthesizing properties in class implementation}}
 - (void) theBestOfTimes {}
 @end
 
index aa67f0a..0f90f61 100644 (file)
@@ -41,10 +41,10 @@ __attribute__((objc_root_class)) @interface ClassBase
 @end
 
 @interface ClassDerived : ClassBase 
-@property (nonatomic, retain) ClassDerived * foo;
+@property (nonatomic, retain) ClassDerived * foo; // expected-warning {{auto property synthesis will not synthesize property 'foo' because it will be synthesize by its super class}}
 @end
 
-@implementation ClassDerived
+@implementation ClassDerived // expected-note {{detected while default synthesizing properties in class implementation}}
 - (void) Meth:(ClassBase*)foo {
   super.foo = foo; // must work with no warning
   [super setFoo:foo]; // works with no warning