From 13e0c90fc1a99bd34969229675bc2e4d6eef0501 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Wed, 11 Nov 2009 22:40:11 +0000 Subject: [PATCH] writable atomic property's setter/getter must be in 'lock' step of either both synthesized or bith user defined. Implements radar 6557233. llvm-svn: 86887 --- .../clang/Basic/DiagnosticSemaKinds.td | 3 + clang/lib/Sema/Sema.h | 6 + clang/lib/Sema/SemaDeclObjC.cpp | 39 +- .../atomoic-property-synnthesis-rules.m | 369 ++++++++++++++++++ clang/test/SemaObjC/property-category-1.m | 1 + 5 files changed, 417 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaObjC/atomoic-property-synnthesis-rules.m diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index f0e1be82a721..3abacd9b3acf 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -269,6 +269,9 @@ def warn_property_attr_mismatch : Warning< def warn_objc_property_copy_missing_on_block : Warning< "'copy' attribute must be specified for the block property " "when -fobjc-gc-only is specified">; +def warn_atomic_property_rule : Warning< + "writable atomic property %0 cannot pair a synthesized setter/getter " + "with a user defined setter/getter">; def err_use_continuation_class : Error< "property declaration in continuation class of %0 is to change a 'readonly' " "property to 'readwrite'">; diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 2fea5539a81d..30c337dff8fa 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1447,6 +1447,12 @@ public: void ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl, ObjCContainerDecl* IDecl, bool IncompleteImpl = false); + + /// AtomicPropertySetterGetterRules - This routine enforces the rule (via + /// warning) when atomic property has one but not the other user-declared + /// setter or getter. + void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl, + ObjCContainerDecl* IDecl); /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns /// true, or false, accordingly. diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 6487835c8aa7..e4482804dd27 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1113,6 +1113,41 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl, assert(false && "invalid ObjCContainerDecl type."); } +void +Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, + ObjCContainerDecl* IDecl) { + // Rules apply in non-GC mode only + if (getLangOptions().getGCMode() != LangOptions::NonGC) + return; + for (ObjCContainerDecl::prop_iterator I = IDecl->prop_begin(), + E = IDecl->prop_end(); + I != E; ++I) { + ObjCPropertyDecl *Property = (*I); + unsigned Attributes = Property->getPropertyAttributes(); + // We only care about readwrite atomic property. + if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) || + !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite)) + continue; + if (const ObjCPropertyImplDecl *PIDecl + = IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) { + if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) + continue; + ObjCMethodDecl *GetterMethod = + IMPDecl->getInstanceMethod(Property->getGetterName()); + ObjCMethodDecl *SetterMethod = + IMPDecl->getInstanceMethod(Property->getSetterName()); + if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) { + SourceLocation MethodLoc = + (GetterMethod ? GetterMethod->getLocation() + : SetterMethod->getLocation()); + Diag(MethodLoc, diag::warn_atomic_property_rule) + << Property->getIdentifier(); + Diag(Property->getLocation(), diag::note_property_declare); + } + } + } +} + /// ActOnForwardClassDeclaration - Action::DeclPtrTy Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, @@ -1608,8 +1643,10 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl, } if (ObjCImplementationDecl *IC=dyn_cast(ClassDecl)) { IC->setAtEndLoc(AtEndLoc); - if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) + if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) { ImplMethodsVsClassMethods(IC, IDecl); + AtomicPropertySetterGetterRules(IC, IDecl); + } } else if (ObjCCategoryImplDecl* CatImplClass = dyn_cast(ClassDecl)) { CatImplClass->setAtEndLoc(AtEndLoc); diff --git a/clang/test/SemaObjC/atomoic-property-synnthesis-rules.m b/clang/test/SemaObjC/atomoic-property-synnthesis-rules.m new file mode 100644 index 000000000000..429d6c0f804d --- /dev/null +++ b/clang/test/SemaObjC/atomoic-property-synnthesis-rules.m @@ -0,0 +1,369 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +/* + Conditions for warning: + 1. the property is atomic + 2. the current @implementation contains an @synthesize for the property + 3. the current @implementation contains a hand-written setter XOR getter + 4. the property is read-write + + Cases marked WARN should warn one the following: + warning: Atomic property 'x' has a synthesized setter and a + manually-implemented getter, which may break atomicity. + warning: Atomic property 'x' has a synthesized getter and a + manually-implemented setter, which may break atomicity. + + Cases not marked WARN only satisfy the indicated subset + of the conditions required to warn. + + There should be 8 warnings. +*/ + +@interface Foo +{ + /* 12 4 */ int GetSet; + /* WARN */ int Get; + /* WARN */ int Set; + /* 12 4 */ int None; + /* 2 4 */ int GetSet_Nonatomic; + /* 234 */ int Get_Nonatomic; + /* 234 */ int Set_Nonatomic; + /* 2 4 */ int None_Nonatomic; + + /* 12 */ int GetSet_ReadOnly; + /* 123 */ int Get_ReadOnly; + /* 123 */ int Set_ReadOnly; + /* 12 */ int None_ReadOnly; + /* 2 */ int GetSet_Nonatomic_ReadOnly; + /* 23 */ int Get_Nonatomic_ReadOnly; + /* 23 */ int Set_Nonatomic_ReadOnly; + /* 2 */ int None_Nonatomic_ReadOnly; + + /* 12 4 */ int GetSet_ReadWriteInExt; + /* WARN */ int Get_ReadWriteInExt; + /* WARN */ int Set_ReadWriteInExt; + /* 12 4 */ int None_ReadWriteInExt; + /* 2 4 */ int GetSet_Nonatomic_ReadWriteInExt; + /* 234 */ int Get_Nonatomic_ReadWriteInExt; + /* 234 */ int Set_Nonatomic_ReadWriteInExt; + /* 2 4 */ int None_Nonatomic_ReadWriteInExt; + + + /* 12 4 */ int GetSet_LateSynthesize; + /* WARN */ int Get_LateSynthesize; + /* WARN */ int Set_LateSynthesize; + /* 12 4 */ int None_LateSynthesize; + /* 2 4 */ int GetSet_Nonatomic_LateSynthesize; + /* 234 */ int Get_Nonatomic_LateSynthesize; + /* 234 */ int Set_Nonatomic_LateSynthesize; + /* 2 4 */ int None_Nonatomic_LateSynthesize; + + /* 12 */ int GetSet_ReadOnly_LateSynthesize; + /* 123 */ int Get_ReadOnly_LateSynthesize; + /* 123 */ int Set_ReadOnly_LateSynthesize; + /* 12 */ int None_ReadOnly_LateSynthesize; + /* 2 */ int GetSet_Nonatomic_ReadOnly_LateSynthesize; + /* 23 */ int Get_Nonatomic_ReadOnly_LateSynthesize; + /* 23 */ int Set_Nonatomic_ReadOnly_LateSynthesize; + /* 2 */ int None_Nonatomic_ReadOnly_LateSynthesize; + + /* 12 4 */ int GetSet_ReadWriteInExt_LateSynthesize; + /* WARN */ int Get_ReadWriteInExt_LateSynthesize; + /* WARN */ int Set_ReadWriteInExt_LateSynthesize; + /* 12 4 */ int None_ReadWriteInExt_LateSynthesize; + /* 2 4 */ int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize; + /* 234 */ int Get_Nonatomic_ReadWriteInExt_LateSynthesize; + /* 234 */ int Set_Nonatomic_ReadWriteInExt_LateSynthesize; + /* 2 4 */ int None_Nonatomic_ReadWriteInExt_LateSynthesize; + + + /* 1 4 */ int GetSet_NoSynthesize; + /* 1 34 */ int Get_NoSynthesize; + /* 1 34 */ int Set_NoSynthesize; + /* 1 4 */ int None_NoSynthesize; + /* 4 */ int GetSet_Nonatomic_NoSynthesize; + /* 34 */ int Get_Nonatomic_NoSynthesize; + /* 34 */ int Set_Nonatomic_NoSynthesize; + /* 4 */ int None_Nonatomic_NoSynthesize; + + /* 1 */ int GetSet_ReadOnly_NoSynthesize; + /* 1 3 */ int Get_ReadOnly_NoSynthesize; + /* 1 3 */ int Set_ReadOnly_NoSynthesize; + /* 1 */ int None_ReadOnly_NoSynthesize; + /* */ int GetSet_Nonatomic_ReadOnly_NoSynthesize; + /* 3 */ int Get_Nonatomic_ReadOnly_NoSynthesize; + /* 3 */ int Set_Nonatomic_ReadOnly_NoSynthesize; + /* */ int None_Nonatomic_ReadOnly_NoSynthesize; + + /* 1 4 */ int GetSet_ReadWriteInExt_NoSynthesize; + /* 1 34 */ int Get_ReadWriteInExt_NoSynthesize; + /* 1 34 */ int Set_ReadWriteInExt_NoSynthesize; + /* 1 4 */ int None_ReadWriteInExt_NoSynthesize; + /* 4 */ int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize; + /* 34 */ int Get_Nonatomic_ReadWriteInExt_NoSynthesize; + /* 34 */ int Set_Nonatomic_ReadWriteInExt_NoSynthesize; + /* 4 */ int None_Nonatomic_ReadWriteInExt_NoSynthesize; +} + +// read-write - might warn +@property int GetSet; +@property int Get; // expected-note {{property declared here}} +@property int Set; // expected-note {{property declared here}} +@property int None; +@property(nonatomic) int GetSet_Nonatomic; +@property(nonatomic) int Get_Nonatomic; +@property(nonatomic) int Set_Nonatomic; +@property(nonatomic) int None_Nonatomic; + +// read-only - must not warn +@property(readonly) int GetSet_ReadOnly; +@property(readonly) int Get_ReadOnly; +@property(readonly) int Set_ReadOnly; +@property(readonly) int None_ReadOnly; +@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly; +@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly; +@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly; +@property(nonatomic,readonly) int None_Nonatomic_ReadOnly; + +// read-only in class, read-write in class extension - might warn +@property(readonly) int GetSet_ReadWriteInExt; +@property(readonly) int Get_ReadWriteInExt; // expected-note {{property declared here}} +@property(readonly) int Set_ReadWriteInExt; // expected-note {{property declared here}} +@property(readonly) int None_ReadWriteInExt; +@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt; +@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt; +@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt; +@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt; + + +// same as above, but @synthesize follows the hand-written methods - might warn +@property int GetSet_LateSynthesize; +@property int Get_LateSynthesize; // expected-note {{property declared here}} +@property int Set_LateSynthesize; // expected-note {{property declared here}} +@property int None_LateSynthesize; +@property(nonatomic) int GetSet_Nonatomic_LateSynthesize; +@property(nonatomic) int Get_Nonatomic_LateSynthesize; +@property(nonatomic) int Set_Nonatomic_LateSynthesize; +@property(nonatomic) int None_Nonatomic_LateSynthesize; + +@property(readonly) int GetSet_ReadOnly_LateSynthesize; +@property(readonly) int Get_ReadOnly_LateSynthesize; +@property(readonly) int Set_ReadOnly_LateSynthesize; +@property(readonly) int None_ReadOnly_LateSynthesize; +@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly_LateSynthesize; +@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly_LateSynthesize; +@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly_LateSynthesize; +@property(nonatomic,readonly) int None_Nonatomic_ReadOnly_LateSynthesize; + +@property(readonly) int GetSet_ReadWriteInExt_LateSynthesize; +@property(readonly) int Get_ReadWriteInExt_LateSynthesize; // expected-note {{property declared here}} +@property(readonly) int Set_ReadWriteInExt_LateSynthesize; // expected-note {{property declared here}} +@property(readonly) int None_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt_LateSynthesize; + + +// same as above, but with no @synthesize - must not warn +@property int GetSet_NoSynthesize; +@property int Get_NoSynthesize; +@property int Set_NoSynthesize; +@property int None_NoSynthesize; +@property(nonatomic) int GetSet_Nonatomic_NoSynthesize; +@property(nonatomic) int Get_Nonatomic_NoSynthesize; +@property(nonatomic) int Set_Nonatomic_NoSynthesize; +@property(nonatomic) int None_Nonatomic_NoSynthesize; + +@property(readonly) int GetSet_ReadOnly_NoSynthesize; +@property(readonly) int Get_ReadOnly_NoSynthesize; +@property(readonly) int Set_ReadOnly_NoSynthesize; +@property(readonly) int None_ReadOnly_NoSynthesize; +@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly_NoSynthesize; +@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly_NoSynthesize; +@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly_NoSynthesize; +@property(nonatomic,readonly) int None_Nonatomic_ReadOnly_NoSynthesize; + +@property(readonly) int GetSet_ReadWriteInExt_NoSynthesize; +@property(readonly) int Get_ReadWriteInExt_NoSynthesize; +@property(readonly) int Set_ReadWriteInExt_NoSynthesize; +@property(readonly) int None_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt_NoSynthesize; + +@end + + +@interface Foo () + +@property(readwrite) int GetSet_ReadWriteInExt; +@property(readwrite) int Get_ReadWriteInExt; +@property(readwrite) int Set_ReadWriteInExt; +@property(readwrite) int None_ReadWriteInExt; +@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt; +@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt; +@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt; +@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt; + +@property(readwrite) int GetSet_ReadWriteInExt_LateSynthesize; +@property(readwrite) int Get_ReadWriteInExt_LateSynthesize; +@property(readwrite) int Set_ReadWriteInExt_LateSynthesize; +@property(readwrite) int None_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt_LateSynthesize; +@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt_LateSynthesize; + +@property(readwrite) int GetSet_ReadWriteInExt_NoSynthesize; +@property(readwrite) int Get_ReadWriteInExt_NoSynthesize; +@property(readwrite) int Set_ReadWriteInExt_NoSynthesize; +@property(readwrite) int None_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt_NoSynthesize; +@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt_NoSynthesize; + +@end + +@implementation Foo + +@synthesize GetSet, Get, Set, None, GetSet_Nonatomic, Get_Nonatomic, Set_Nonatomic, None_Nonatomic; +@synthesize GetSet_ReadOnly, Get_ReadOnly, Set_ReadOnly, None_ReadOnly, GetSet_Nonatomic_ReadOnly, Get_Nonatomic_ReadOnly, Set_Nonatomic_ReadOnly, None_Nonatomic_ReadOnly; +@synthesize GetSet_ReadWriteInExt, Get_ReadWriteInExt, Set_ReadWriteInExt, None_ReadWriteInExt, GetSet_Nonatomic_ReadWriteInExt, Get_Nonatomic_ReadWriteInExt, Set_Nonatomic_ReadWriteInExt, None_Nonatomic_ReadWriteInExt; + +#define GET(x) \ + -(int) x { return self->x; } +#define SET(x) \ + -(void) set##x:(int)value { self->x = value; } + +GET(GetSet) +SET(GetSet) +GET(Get) // expected-warning {{writable atomic property 'Get' cannot pair a synthesized setter/getter with a user defined setter/getter}} +SET(Set) // expected-warning {{writable atomic property 'Set' cannot pair a synthesized setter/getter with a user defined setter/getter}} +GET(GetSet_Nonatomic) +SET(GetSet_Nonatomic) +GET(Get_Nonatomic) +SET(Set_Nonatomic) + +GET(GetSet_ReadOnly) +SET(GetSet_ReadOnly) +GET(Get_ReadOnly) +SET(Set_ReadOnly) +GET(GetSet_Nonatomic_ReadOnly) +SET(GetSet_Nonatomic_ReadOnly) +GET(Get_Nonatomic_ReadOnly) +SET(Set_Nonatomic_ReadOnly) + +GET(GetSet_ReadWriteInExt) +SET(GetSet_ReadWriteInExt) +GET(Get_ReadWriteInExt) // expected-warning {{writable atomic property 'Get_ReadWriteInExt' cannot pair a synthesized setter/getter with a user defined setter/getter}} +SET(Set_ReadWriteInExt) // expected-warning {{writable atomic property 'Set_ReadWriteInExt' cannot pair a synthesized setter/getter with a user defined setter/getter}} +GET(GetSet_Nonatomic_ReadWriteInExt) +SET(GetSet_Nonatomic_ReadWriteInExt) +GET(Get_Nonatomic_ReadWriteInExt) +SET(Set_Nonatomic_ReadWriteInExt) + + +GET(GetSet_LateSynthesize) +SET(GetSet_LateSynthesize) +GET(Get_LateSynthesize) // expected-warning {{writable atomic property 'Get_LateSynthesize' cannot pair a synthesized setter/getter with a user defined setter/getter}} +SET(Set_LateSynthesize) // expected-warning {{writable atomic property 'Set_LateSynthesize' cannot pair a synthesized setter/getter with a user defined setter/getter}} +GET(GetSet_Nonatomic_LateSynthesize) +SET(GetSet_Nonatomic_LateSynthesize) +GET(Get_Nonatomic_LateSynthesize) +SET(Set_Nonatomic_LateSynthesize) + +GET(GetSet_ReadOnly_LateSynthesize) +SET(GetSet_ReadOnly_LateSynthesize) +GET(Get_ReadOnly_LateSynthesize) +SET(Set_ReadOnly_LateSynthesize) +GET(GetSet_Nonatomic_ReadOnly_LateSynthesize) +SET(GetSet_Nonatomic_ReadOnly_LateSynthesize) +GET(Get_Nonatomic_ReadOnly_LateSynthesize) +SET(Set_Nonatomic_ReadOnly_LateSynthesize) + +GET(GetSet_ReadWriteInExt_LateSynthesize) +SET(GetSet_ReadWriteInExt_LateSynthesize) +GET(Get_ReadWriteInExt_LateSynthesize) // expected-warning {{writable atomic property 'Get_ReadWriteInExt_LateSynthesize' cannot pair a synthesized setter/getter with a user defined setter/getter}} +SET(Set_ReadWriteInExt_LateSynthesize) // expected-warning {{writable atomic property 'Set_ReadWriteInExt_LateSynthesize' cannot pair a synthesized setter/getter with a user defined setter/getter}} +GET(GetSet_Nonatomic_ReadWriteInExt_LateSynthesize) +SET(GetSet_Nonatomic_ReadWriteInExt_LateSynthesize) +GET(Get_Nonatomic_ReadWriteInExt_LateSynthesize) +SET(Set_Nonatomic_ReadWriteInExt_LateSynthesize) + + +GET(GetSet_NoSynthesize) +SET(GetSet_NoSynthesize) +GET(Get_NoSynthesize) +SET(Set_NoSynthesize) +GET(GetSet_Nonatomic_NoSynthesize) +SET(GetSet_Nonatomic_NoSynthesize) +GET(Get_Nonatomic_NoSynthesize) +SET(Set_Nonatomic_NoSynthesize) + +GET(GetSet_ReadOnly_NoSynthesize) +SET(GetSet_ReadOnly_NoSynthesize) +GET(Get_ReadOnly_NoSynthesize) +SET(Set_ReadOnly_NoSynthesize) +GET(GetSet_Nonatomic_ReadOnly_NoSynthesize) +SET(GetSet_Nonatomic_ReadOnly_NoSynthesize) +GET(Get_Nonatomic_ReadOnly_NoSynthesize) +SET(Set_Nonatomic_ReadOnly_NoSynthesize) + +GET(GetSet_ReadWriteInExt_NoSynthesize) +SET(GetSet_ReadWriteInExt_NoSynthesize) +GET(Get_ReadWriteInExt_NoSynthesize) +SET(Set_ReadWriteInExt_NoSynthesize) +GET(GetSet_Nonatomic_ReadWriteInExt_NoSynthesize) +SET(GetSet_Nonatomic_ReadWriteInExt_NoSynthesize) +GET(Get_Nonatomic_ReadWriteInExt_NoSynthesize) +SET(Set_Nonatomic_ReadWriteInExt_NoSynthesize) + + +// late synthesize - follows getter/setter implementations + +@synthesize GetSet_LateSynthesize, Get_LateSynthesize, Set_LateSynthesize, None_LateSynthesize, GetSet_Nonatomic_LateSynthesize, Get_Nonatomic_LateSynthesize, Set_Nonatomic_LateSynthesize, None_Nonatomic_LateSynthesize; +@synthesize GetSet_ReadOnly_LateSynthesize, Get_ReadOnly_LateSynthesize, Set_ReadOnly_LateSynthesize, None_ReadOnly_LateSynthesize, GetSet_Nonatomic_ReadOnly_LateSynthesize, Get_Nonatomic_ReadOnly_LateSynthesize, Set_Nonatomic_ReadOnly_LateSynthesize, None_Nonatomic_ReadOnly_LateSynthesize; +@synthesize GetSet_ReadWriteInExt_LateSynthesize, Get_ReadWriteInExt_LateSynthesize, Set_ReadWriteInExt_LateSynthesize, None_ReadWriteInExt_LateSynthesize, GetSet_Nonatomic_ReadWriteInExt_LateSynthesize, Get_Nonatomic_ReadWriteInExt_LateSynthesize, Set_Nonatomic_ReadWriteInExt_LateSynthesize, None_Nonatomic_ReadWriteInExt_LateSynthesize; + +// no synthesize - use dynamic instead + +@dynamic GetSet_NoSynthesize, Get_NoSynthesize, Set_NoSynthesize, None_NoSynthesize, GetSet_Nonatomic_NoSynthesize, Get_Nonatomic_NoSynthesize, Set_Nonatomic_NoSynthesize, None_Nonatomic_NoSynthesize; +@dynamic GetSet_ReadOnly_NoSynthesize, Get_ReadOnly_NoSynthesize, Set_ReadOnly_NoSynthesize, None_ReadOnly_NoSynthesize, GetSet_Nonatomic_ReadOnly_NoSynthesize, Get_Nonatomic_ReadOnly_NoSynthesize, Set_Nonatomic_ReadOnly_NoSynthesize, None_Nonatomic_ReadOnly_NoSynthesize; +@dynamic GetSet_ReadWriteInExt_NoSynthesize, Get_ReadWriteInExt_NoSynthesize, Set_ReadWriteInExt_NoSynthesize, None_ReadWriteInExt_NoSynthesize, GetSet_Nonatomic_ReadWriteInExt_NoSynthesize, Get_Nonatomic_ReadWriteInExt_NoSynthesize, Set_Nonatomic_ReadWriteInExt_NoSynthesize, None_Nonatomic_ReadWriteInExt_NoSynthesize; + +@end + +/* +// the following method should cause a warning along the lines of +// :warning: Atomic property 'x' cannot pair a synthesized setter/getter with a manually implemented setter/getter +- (void) setX: (int) aValue +{ + x = aValue; +} + +// no warning 'cause this is nonatomic +- (void) setY: (int) aValue +{ + y = aValue; +} + +// the following method should cause a warning along the lines of +// :warning: Atomic property 'x' cannot pair a synthesized setter/getter with a manually implemented setter/getter +- (int) j +{ + return j; +} + +// no warning 'cause this is nonatomic +- (int) k +{ + return k; +} +@end +*/ +int main (int argc, const char * argv[]) { + return 0; +} diff --git a/clang/test/SemaObjC/property-category-1.m b/clang/test/SemaObjC/property-category-1.m index 6695239fd352..fa9d4c8c4bb9 100644 --- a/clang/test/SemaObjC/property-category-1.m +++ b/clang/test/SemaObjC/property-category-1.m @@ -24,6 +24,7 @@ - (void) myAnotherobjectSetter : (int)val { _Anotherobject = val; } +- (int) Anotherobject { return _Anotherobject; } @end int main(int argc, char **argv) {