diff options
author | Steve Naroff <snaroff@apple.com> | 2009-03-03 15:43:24 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2009-03-03 15:43:24 +0000 |
commit | 15edf0de6b5bc9ae227bcc9658a157ac30efd92e (patch) | |
tree | 9ba515b45da108e228c73bfc9c6389f10d7bfff0 | |
parent | ca33129bb28b05938c3e6c9f8a66165b5cceb4dd (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.def | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 1 | ||||
-rw-r--r-- | test/SemaObjC/property-inherited.m | 44 |
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 |