diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-11-11 22:40:11 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-11-11 22:40:11 +0000 |
commit | 7ca8b0694840385d707689eba9ad965e7b28c8cb (patch) | |
tree | effabc731ec70772deb7bada7b86cdab6fc81534 /lib/Sema/SemaDeclObjC.cpp | |
parent | f35f828f9883123772a9731af190a608f3236ef4 (diff) |
writable atomic property's setter/getter must be in 'lock' step of
either both synthesized or bith user defined.
Implements radar 6557233.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86887 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclObjC.cpp')
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 6487835c8a..e4482804dd 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/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<ObjCImplementationDecl>(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<ObjCCategoryImplDecl>(ClassDecl)) { CatImplClass->setAtEndLoc(AtEndLoc); |