Add -Wcustom-atomic-properties which warns if an atomic-by-default property has custom getter or setter.
The rationale is that it is highly likely that the user's getter/setter isn't atomically implemented. Off by default.
Addresses rdar://8782645.
-Wcustom-atomic-properties and -Wimplicit-atomic-properties are under the -Watomic-properties group.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124609 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 88ad4d7..2f5be47 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -1081,7 +1081,32 @@
E = IDecl->prop_end();
I != E; ++I) {
ObjCPropertyDecl *Property = (*I);
+ ObjCMethodDecl *GetterMethod = 0;
+ ObjCMethodDecl *SetterMethod = 0;
+ bool LookedUpGetterSetter = false;
+
unsigned Attributes = Property->getPropertyAttributes();
+ unsigned AttributesAsWrittern = Property->getPropertyAttributesAsWritten();
+
+ if (!(AttributesAsWrittern & ObjCPropertyDecl::OBJC_PR_atomic) &&
+ !(AttributesAsWrittern & ObjCPropertyDecl::OBJC_PR_nonatomic)) {
+ GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName());
+ SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName());
+ LookedUpGetterSetter = true;
+ if (GetterMethod) {
+ Diag(GetterMethod->getLocation(),
+ diag::warn_default_atomic_custom_getter_setter)
+ << Property->getIdentifier();
+ Diag(Property->getLocation(), diag::note_property_declare);
+ }
+ if (SetterMethod) {
+ Diag(SetterMethod->getLocation(),
+ diag::warn_default_atomic_custom_getter_setter)
+ << Property->getIdentifier();
+ Diag(Property->getLocation(), diag::note_property_declare);
+ }
+ }
+
// We only care about readwrite atomic property.
if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) ||
!(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite))
@@ -1090,10 +1115,11 @@
= IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) {
if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
continue;
- ObjCMethodDecl *GetterMethod =
- IMPDecl->getInstanceMethod(Property->getGetterName());
- ObjCMethodDecl *SetterMethod =
- IMPDecl->getInstanceMethod(Property->getSetterName());
+ if (!LookedUpGetterSetter) {
+ GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName());
+ SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName());
+ LookedUpGetterSetter = true;
+ }
if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) {
SourceLocation MethodLoc =
(GetterMethod ? GetterMethod->getLocation()