summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2013-10-04 18:06:08 +0000
committerFariborz Jahanian <fjahanian@apple.com>2013-10-04 18:06:08 +0000
commitb809a0e2806224e14855dd4efd6fee3d4eecf423 (patch)
tree6b38df6a95c0eee541adf5f19c62f1cb07cd564f
parent1c26db861ba5d5a2dd545164d45760c1e4bb14d0 (diff)
downloadbcm5719-llvm-b809a0e2806224e14855dd4efd6fee3d4eecf423.tar.gz
bcm5719-llvm-b809a0e2806224e14855dd4efd6fee3d4eecf423.zip
ObjectiveC. Allow readonly properties without an explicit ownership
(assign/unsafe_unretained/weak/retain/strong/copy) in super class to be overridden by a property with any explicit ownership in the subclass. // rdar://15014468 llvm-svn: 191971
-rw-r--r--clang/include/clang/Sema/Sema.h3
-rw-r--r--clang/lib/Sema/SemaObjCProperty.cpp58
-rw-r--r--clang/test/SemaObjC/property-ownership-attr.m19
3 files changed, 55 insertions, 25 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a7df4365b5b..f0dd57fa8b9 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -6645,7 +6645,8 @@ public:
void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
ObjCPropertyDecl *SuperProperty,
- const IdentifierInfo *Name);
+ const IdentifierInfo *Name,
+ bool OverridingProtocolProperty);
void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
ObjCInterfaceDecl *ID);
diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp
index cd5be5e35db..5323ad47ca9 100644
--- a/clang/lib/Sema/SemaObjCProperty.cpp
+++ b/clang/lib/Sema/SemaObjCProperty.cpp
@@ -126,7 +126,7 @@ CheckPropertyAgainstProtocol(Sema &S, ObjCPropertyDecl *Prop,
DeclContext::lookup_result R = Proto->lookup(Prop->getDeclName());
for (unsigned I = 0, N = R.size(); I != N; ++I) {
if (ObjCPropertyDecl *ProtoProp = dyn_cast<ObjCPropertyDecl>(R[I])) {
- S.DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier());
+ S.DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), true);
return;
}
}
@@ -208,7 +208,7 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
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])) {
- DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier());
+ DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier(), false);
FoundInSuper = true;
break;
}
@@ -1353,31 +1353,41 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
void
Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
ObjCPropertyDecl *SuperProperty,
- const IdentifierInfo *inheritedName) {
+ const IdentifierInfo *inheritedName,
+ bool OverridingProtocolProperty) {
ObjCPropertyDecl::PropertyAttributeKind CAttr =
- Property->getPropertyAttributes();
+ Property->getPropertyAttributes();
ObjCPropertyDecl::PropertyAttributeKind SAttr =
- SuperProperty->getPropertyAttributes();
- if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly)
- && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite))
- Diag(Property->getLocation(), diag::warn_readonly_property)
- << Property->getDeclName() << inheritedName;
- if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
- != (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
- Diag(Property->getLocation(), diag::warn_property_attribute)
- << Property->getDeclName() << "copy" << inheritedName;
- else if (!(SAttr & ObjCPropertyDecl::OBJC_PR_readonly)){
- unsigned CAttrRetain =
- (CAttr &
- (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong));
- unsigned SAttrRetain =
- (SAttr &
- (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong));
- bool CStrong = (CAttrRetain != 0);
- bool SStrong = (SAttrRetain != 0);
- if (CStrong != SStrong)
+ SuperProperty->getPropertyAttributes();
+
+ // We allow readonly properties without an explicit ownership
+ // (assign/unsafe_unretained/weak/retain/strong/copy) in super class
+ // to be overridden by a property with any explicit ownership in the subclass.
+ if (!OverridingProtocolProperty &&
+ !getOwnershipRule(SAttr) && getOwnershipRule(CAttr))
+ ;
+ else {
+ if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly)
+ && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite))
+ Diag(Property->getLocation(), diag::warn_readonly_property)
+ << Property->getDeclName() << inheritedName;
+ if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
+ != (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
Diag(Property->getLocation(), diag::warn_property_attribute)
- << Property->getDeclName() << "retain (or strong)" << inheritedName;
+ << Property->getDeclName() << "copy" << inheritedName;
+ else if (!(SAttr & ObjCPropertyDecl::OBJC_PR_readonly)){
+ unsigned CAttrRetain =
+ (CAttr &
+ (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong));
+ unsigned SAttrRetain =
+ (SAttr &
+ (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong));
+ bool CStrong = (CAttrRetain != 0);
+ bool SStrong = (SAttrRetain != 0);
+ if (CStrong != SStrong)
+ Diag(Property->getLocation(), diag::warn_property_attribute)
+ << Property->getDeclName() << "retain (or strong)" << inheritedName;
+ }
}
if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)
diff --git a/clang/test/SemaObjC/property-ownership-attr.m b/clang/test/SemaObjC/property-ownership-attr.m
new file mode 100644
index 00000000000..f83c560acb3
--- /dev/null
+++ b/clang/test/SemaObjC/property-ownership-attr.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar://15014468
+
+@protocol P
+ @property(readonly) id z;
+@end
+
+@interface Foo
+ @property (readonly) id x;
+@end
+
+@interface MutableFoo : Foo
+ @property (copy) id x;
+@end
+
+@interface Foo (Cat) <P>
+@property (copy) id z; // expected-warning {{'copy' attribute on property 'z' does not match the property inherited from 'P'}}
+@end
+
OpenPOWER on IntegriCloud