aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--lib/Sema/SemaObjCProperty.cpp15
-rw-r--r--test/SemaObjCXX/property-reference.mm2
-rw-r--r--test/SemaObjCXX/property-synthesis-error.mm29
4 files changed, 48 insertions, 1 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index fc8c636bb3..d4c118b447 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -501,6 +501,9 @@ def warn_atomic_property_rule : Warning<
"writable atomic property %0 cannot pair a synthesized setter/getter "
"with a user defined setter/getter">,
InGroup<DiagGroup<"atomic-property-with-user-defined-accessor">>;
+def warn_atomic_property_nontrivial_assign_op : Warning<
+ "atomic property of type %0 synthesizing setter using non-trivial assignment"
+ "operator">, InGroup<DiagGroup<"objc-property-atomic-setter-synthesis">>;
def warn_ownin_getter_rule : Warning<
"property's synthesized getter follows Cocoa naming"
" convention for returning 'owned' objects">,
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 880e9bfb2b..5a54f57580 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -16,6 +16,7 @@
#include "clang/Sema/Initialization.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprObjC.h"
+#include "clang/AST/ExprCXX.h"
#include "llvm/ADT/DenseSet.h"
using namespace clang;
@@ -800,6 +801,20 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
VK_LValue, SourceLocation());
ExprResult Res = BuildBinOp(S, lhs->getLocEnd(),
BO_Assign, lhs, rhs);
+ if (property->getPropertyAttributes() &
+ ObjCPropertyDecl::OBJC_PR_atomic) {
+ Expr *callExpr = Res.takeAs<Expr>();
+ if (const CXXOperatorCallExpr *CXXCE =
+ dyn_cast_or_null<CXXOperatorCallExpr>(callExpr)) {
+ const CallExpr *CE = cast<CallExpr>(CXXCE);
+ if (const FunctionDecl *FuncDecl = CE->getDirectCallee()) {
+ if (!FuncDecl->isTrivial())
+ Diag(PropertyLoc,
+ diag::warn_atomic_property_nontrivial_assign_op)
+ << property->getType();
+ }
+ }
+ }
PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>());
}
}
diff --git a/test/SemaObjCXX/property-reference.mm b/test/SemaObjCXX/property-reference.mm
index 11818d575a..98bc727300 100644
--- a/test/SemaObjCXX/property-reference.mm
+++ b/test/SemaObjCXX/property-reference.mm
@@ -29,7 +29,7 @@ typedef const TCPPObject& CREF_TCPPObject;
@implementation TNSObject
@synthesize cppObjectNonAtomic;
-@synthesize cppObjectAtomic;
+@synthesize cppObjectAtomic; // expected-warning{{atomic property of type 'CREF_TCPPObject' (aka 'const TCPPObject &') synthesizing setter using non-trivial assignmentoperator}}
@dynamic cppObjectDynamic;
- (const TCPPObject&) cppObjectNonAtomic
diff --git a/test/SemaObjCXX/property-synthesis-error.mm b/test/SemaObjCXX/property-synthesis-error.mm
index c67f0a45c7..f79a56db6c 100644
--- a/test/SemaObjCXX/property-synthesis-error.mm
+++ b/test/SemaObjCXX/property-synthesis-error.mm
@@ -30,3 +30,32 @@ int main(void)
{
return 0;
}
+
+// rdar://6137845
+class TCPPObject
+{
+public:
+ TCPPObject(const TCPPObject& inObj);
+ TCPPObject();
+ ~TCPPObject();
+ TCPPObject& operator=(const TCPPObject& inObj);
+private:
+ void* fData;
+};
+
+@interface MyDocument
+{
+@private
+ TCPPObject _cppObject;
+ TCPPObject _ncppObject;
+}
+@property (assign, readwrite) const TCPPObject& cppObject;
+@property (assign, readwrite, nonatomic) const TCPPObject& ncppObject;
+@end
+
+@implementation MyDocument
+
+@synthesize cppObject = _cppObject; // expected-warning {{atomic property of type 'const TCPPObject &' synthesizing setter using non-trivial assignmentoperator}}
+@synthesize ncppObject = _ncppObject;
+
+@end