aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2009-03-03 15:43:24 +0000
committerSteve Naroff <snaroff@apple.com>2009-03-03 15:43:24 +0000
commit15edf0de6b5bc9ae227bcc9658a157ac30efd92e (patch)
tree9ba515b45da108e228c73bfc9c6389f10d7bfff0
parentca33129bb28b05938c3e6c9f8a66165b5cceb4dd (diff)
Fix <rdar://problem/6497242> Inherited overridden protocol declared objects don't work.
Change Sema::DiagnosePropertyMismatch() to check for type compatibility (rather than type equivalence, which is too strict). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65949 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.def4
-rw-r--r--lib/Sema/SemaDeclObjC.cpp20
-rw-r--r--lib/Sema/SemaExprObjC.cpp1
-rw-r--r--test/SemaObjC/property-inherited.m44
4 files changed, 61 insertions, 8 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.def b/include/clang/Basic/DiagnosticSemaKinds.def
index 83fe15ebf8..4138436a88 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.def
+++ b/include/clang/Basic/DiagnosticSemaKinds.def
@@ -144,8 +144,8 @@ DIAG(warn_readonly_property, WARNING,
"'readwrite' of property inherited from %1")
DIAG(warn_property_attribute, WARNING,
"property %0 '%1' attribute does not match the property inherited from %2")
-DIAG(warn_property_type, WARNING,
- "property type %0 does not match property type inherited from %1")
+DIAG(warn_property_types_are_incompatible, WARNING,
+ "property type %0 is incompatible with type %1 inherited from %2")
DIAG(err_undef_interface, ERROR,
"cannot find interface declaration for %0")
DIAG(warn_dup_category_def, WARNING,
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 19a2a636db..1ca9d8da9a 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -320,12 +320,20 @@ Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
if (Property->getGetterName() != SuperProperty->getGetterName())
Diag(Property->getLocation(), diag::warn_property_attribute)
<< Property->getDeclName() << "getter" << inheritedName;
-
- if (Context.getCanonicalType(Property->getType()) !=
- Context.getCanonicalType(SuperProperty->getType()))
- Diag(Property->getLocation(), diag::warn_property_type)
- << Property->getType() << inheritedName;
-
+
+ QualType LHSType =
+ Context.getCanonicalType(SuperProperty->getType());
+ QualType RHSType =
+ Context.getCanonicalType(Property->getType());
+
+ if (!Context.typesAreCompatible(LHSType, RHSType)) {
+ // FIXME: Incorporate this test with typesAreCompatible.
+ if (LHSType->isObjCQualifiedIdType() && RHSType->isObjCQualifiedIdType())
+ if (ObjCQualifiedIdTypesAreCompatible(LHSType, RHSType, false))
+ return;
+ Diag(Property->getLocation(), diag::warn_property_types_are_incompatible)
+ << Property->getType() << SuperProperty->getType() << inheritedName;
+ }
}
/// ComparePropertiesInBaseAndSuper - This routine compares property
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index f571068822..8b452af9e8 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -540,6 +540,7 @@ static bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
/// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an
/// ObjCQualifiedIDType.
+/// FIXME: Move to ASTContext::typesAreCompatible() and friends.
bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
bool compare) {
// Allow id<P..> and an 'id' or void* type in all cases.
diff --git a/test/SemaObjC/property-inherited.m b/test/SemaObjC/property-inherited.m
new file mode 100644
index 0000000000..7669e44dab
--- /dev/null
+++ b/test/SemaObjC/property-inherited.m
@@ -0,0 +1,44 @@
+// RUN: clang %s -fsyntax-only -verify
+
+// <rdar://problem/6497242> Inherited overridden protocol declared objects don't work
+
+@protocol NSObject @end
+@interface NSObject @end
+
+@protocol FooDelegate<NSObject>
+@optional
+- (void)fooTask;
+@end
+
+@protocol BarDelegate<NSObject, FooDelegate>
+@optional
+- (void)barTask;
+@end
+
+@interface Foo : NSObject {
+ id _delegate;
+}
+@property(nonatomic, assign) id<FooDelegate> delegate;
+@property(nonatomic, assign) id<BarDelegate> delegate2;
+@end
+@interface Bar : Foo {
+}
+@property(nonatomic, assign) id<BarDelegate> delegate;
+@property(nonatomic, assign) id<FooDelegate> delegate2; // expected-warning{{property type 'id<FooDelegate>' is incompatible with type 'id<BarDelegate>' inherited from 'Foo'}}
+@end
+
+@interface NSData @end
+
+@interface NSMutableData : NSData @end
+
+@interface Base : NSData
+@property(assign) id ref;
+@property(assign) Base *p_base;
+@property(assign) NSMutableData *p_data;
+@end
+
+@interface Data : Base
+@property(assign) NSData *ref;
+@property(assign) Data *p_base;
+@property(assign) NSData *p_data; // expected-warning{{property type 'NSData *' is incompatible with type 'NSMutableData *' inherited from 'Base'}}
+@end