diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2012-08-21 21:45:58 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2012-08-21 21:45:58 +0000 |
commit | dad633b0a0955ceb4579e9508224562ad41b6a8d (patch) | |
tree | 0290e45e44e48d818d5f35840852c75a0aa64b39 | |
parent | c568e2f801a62e442cbbd823b71f70175715661f (diff) |
objective-C: Change rules for overriding properties in
class extensions a little. clang now allows readonly property
with no ownership rule (assign, unsafe_unretained, weak, retain,
strong, or copy) with a readwrite property with an ownership rule.
// rdar://12103400
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162319 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaObjCProperty.cpp | 38 | ||||
-rw-r--r-- | test/SemaObjC/continuation-class-err.m | 4 | ||||
-rw-r--r-- | test/SemaObjC/property-in-class-extension-1.m | 49 |
3 files changed, 76 insertions, 15 deletions
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index 6aa59229fa..a8726cb931 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -102,6 +102,15 @@ static void checkARCPropertyDecl(Sema &S, ObjCPropertyDecl *property) { << propertyLifetime; } +static unsigned deduceWeakPropertyFromType(Sema &S, QualType T) { + if ((S.getLangOpts().getGC() != LangOptions::NonGC && + T.isObjCGCWeak()) || + (S.getLangOpts().ObjCAutoRefCount && + T.getObjCLifetime() == Qualifiers::OCL_Weak)) + return ObjCDeclSpec::DQ_PR_weak; + return 0; +} + Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, @@ -114,12 +123,8 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, unsigned Attributes = ODS.getPropertyAttributes(); TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S); QualType T = TSI->getType(); - if ((getLangOpts().getGC() != LangOptions::NonGC && - T.isObjCGCWeak()) || - (getLangOpts().ObjCAutoRefCount && - T.getObjCLifetime() == Qualifiers::OCL_Weak)) - Attributes |= ObjCDeclSpec::DQ_PR_weak; - + Attributes |= deduceWeakPropertyFromType(*this, T); + bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) || // default is readwrite! !(Attributes & ObjCDeclSpec::DQ_PR_readonly)); @@ -236,6 +241,15 @@ static bool LocPropertyAttribute( ASTContext &Context, const char *attrName, } +static unsigned getMemoryModel(unsigned attr) { + return attr & (ObjCPropertyDecl::OBJC_PR_assign | + ObjCPropertyDecl::OBJC_PR_retain | + ObjCPropertyDecl::OBJC_PR_copy | + ObjCPropertyDecl::OBJC_PR_weak | + ObjCPropertyDecl::OBJC_PR_strong | + ObjCPropertyDecl::OBJC_PR_unsafe_unretained); +} + Decl * Sema::HandlePropertyInClassExtension(Scope *S, SourceLocation AtLoc, @@ -342,13 +356,11 @@ Sema::HandlePropertyInClassExtension(Scope *S, // with continuation class's readwrite property attribute! unsigned PIkind = PIDecl->getPropertyAttributesAsWritten(); if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) { - unsigned retainCopyNonatomic = - (ObjCPropertyDecl::OBJC_PR_retain | - ObjCPropertyDecl::OBJC_PR_strong | - ObjCPropertyDecl::OBJC_PR_copy | - ObjCPropertyDecl::OBJC_PR_nonatomic); - if ((Attributes & retainCopyNonatomic) != - (PIkind & retainCopyNonatomic)) { + PIkind |= deduceWeakPropertyFromType(*this, PIDecl->getType()); + unsigned ClassExtensionMemoryModel = getMemoryModel(Attributes); + unsigned PrimaryClassMemoryModel = getMemoryModel(PIkind); + if (PrimaryClassMemoryModel && ClassExtensionMemoryModel && + (PrimaryClassMemoryModel != ClassExtensionMemoryModel)) { Diag(AtLoc, diag::warn_property_attr_mismatch); Diag(PIDecl->getLocation(), diag::note_property_declare); } diff --git a/test/SemaObjC/continuation-class-err.m b/test/SemaObjC/continuation-class-err.m index ceb8ee90c9..8378c3f9f8 100644 --- a/test/SemaObjC/continuation-class-err.m +++ b/test/SemaObjC/continuation-class-err.m @@ -5,13 +5,13 @@ id _object; id _object1; } -@property(readonly) id object; // expected-note {{property declared here}} +@property(readonly) id object; @property(readwrite, assign) id object1; // expected-note {{property declared here}} @property (readonly) int indentLevel; @end @interface ReadOnly () -@property(readwrite, copy) id object; // expected-warning {{property attribute in class extension does not match the primary class}} +@property(readwrite, copy) id object; // Ok. declaring memory model in class extension - primary has none. @property(readonly) id object1; // expected-error {{illegal redeclaration of property in class extension 'ReadOnly' (attribute must be 'readwrite', while its primary must be 'readonly')}} @property (readwrite, assign) int indentLevel; // OK. assign the default in any case. @end diff --git a/test/SemaObjC/property-in-class-extension-1.m b/test/SemaObjC/property-in-class-extension-1.m new file mode 100644 index 0000000000..fb02157c7e --- /dev/null +++ b/test/SemaObjC/property-in-class-extension-1.m @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Weverything %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Weverything %s +// rdar://12103400 + +@class NSString; + +@interface MyClass + +@property (nonatomic, readonly) NSString* addingMemoryModel; + +@property (nonatomic, copy, readonly) NSString* matchingMemoryModel; + +@property (nonatomic, retain, readonly) NSString* addingNoNewMemoryModel; + +@property (readonly) NSString* none; +@property (readonly) NSString* none1; + +@property (assign, readonly) NSString* changeMemoryModel; // expected-note {{property declared here}} + +@property (readonly) __weak id weak_prop; +@property (readonly) __weak id weak_prop1; + +@property (assign, readonly) NSString* assignProperty; + +@property (readonly) NSString* readonlyProp; + + + +@end + +@interface MyClass () +{ + NSString* _name; +} + +@property (nonatomic, copy) NSString* addingMemoryModel; +@property (nonatomic, copy) NSString* matchingMemoryModel; +@property () NSString* addingNoNewMemoryModel; +@property () NSString* none; +@property (readwrite) NSString* none1; + +@property (retain) NSString* changeMemoryModel; // expected-warning {{property attribute in class extension does not match the primary class}} +@property () __weak id weak_prop; +@property (readwrite) __weak id weak_prop1; + +@property () NSString* assignProperty; +@property (assign) NSString* readonlyProp; +@end + |