[Objective-C Sema]. Warn when an indirectly overridden property
authorFariborz Jahanian <fjahanian@apple.com>
Sat, 15 Feb 2014 00:04:36 +0000 (00:04 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sat, 15 Feb 2014 00:04:36 +0000 (00:04 +0000)
mismatches the one declared in current class; in addition to
those that are directly overridden.
// rdar://15967517

llvm-svn: 201446

clang/lib/Sema/SemaObjCProperty.cpp
clang/test/SemaObjC/property-inherited.m

index c8358bc..992ac1d 100644 (file)
@@ -204,7 +204,8 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
   if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
     // For a class, compare the property against a property in our superclass.
     bool FoundInSuper = false;
-    if (ObjCInterfaceDecl *Super = IFace->getSuperClass()) {
+    ObjCInterfaceDecl *CurrentInterfaceDecl = IFace;
+    while (ObjCInterfaceDecl *Super = CurrentInterfaceDecl->getSuperClass()) {
       DeclContext::lookup_result R = Super->lookup(Res->getDeclName());
       for (unsigned I = 0, N = R.size(); I != N; ++I) {
         if (ObjCPropertyDecl *SuperProp = dyn_cast<ObjCPropertyDecl>(R[I])) {
@@ -213,12 +214,17 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
           break;
         }
       }
+      if (FoundInSuper)
+        break;
+      else
+        CurrentInterfaceDecl = Super;
     }
 
     if (FoundInSuper) {
       // Also compare the property against a property in our protocols.
-      for (ObjCInterfaceDecl::protocol_iterator P = IFace->protocol_begin(),
-                                             PEnd = IFace->protocol_end();
+      for (ObjCInterfaceDecl::protocol_iterator
+            P = CurrentInterfaceDecl->protocol_begin(),
+            PEnd = CurrentInterfaceDecl->protocol_end();
            P != PEnd; ++P) {
         CheckPropertyAgainstProtocol(*this, Res, *P, KnownProtos);
       }
index f5f1b42..cd223dd 100644 (file)
 @property(assign) Data *p_base;        
 @property(assign) NSData *p_data;      // expected-warning{{property type 'NSData *' is incompatible with type 'NSMutableData *' inherited from 'Base'}}
 @end
+
+// rdar://15967517
+@protocol P1
+@property (nonatomic) void* selected;
+@end
+
+@protocol P2
+@property (nonatomic) void* selected; // expected-note {{property declared here}}
+@end
+
+@interface MKAnnotationView <P1>
+@property (nonatomic) void* selected; // expected-note {{property declared here}}
+@property (nonatomic) char selected2;
+@end
+
+@interface Parent : MKAnnotationView <P2>
+@property (nonatomic) void* selected1; // expected-note {{property declared here}}
+@property (nonatomic) char selected2;
+@end
+
+@interface Child : Parent
+@property (nonatomic) char selected; // expected-warning {{property type 'char' is incompatible with type 'void *' inherited from 'MKAnnotationView'}} \
+                                    // expected-warning {{property type 'char' is incompatible with type 'void *' inherited from 'P2'}}
+@property (nonatomic) char selected1; // expected-warning {{property type 'char' is incompatible with type 'void *' inherited from 'Parent'}}
+@property (nonatomic) char selected2;
+@end