From: Fariborz Jahanian Date: Thu, 6 Oct 2011 18:38:18 +0000 (+0000) Subject: objc++: For atomic properties of c++ class objec typet, appropriate X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=57e264e9f4ff0a72f3585a960cdf63437b76fa93;p=clang objc++: For atomic properties of c++ class objec typet, appropriate operator= is called. Issue a warning for non-trivial case until runtime support is provided. // rdar://6137845 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141302 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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>; +def warn_atomic_property_nontrivial_assign_op : Warning< + "atomic property of type %0 synthesizing setter using non-trivial assignment" + "operator">, InGroup>; 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(); + if (const CXXOperatorCallExpr *CXXCE = + dyn_cast_or_null(callExpr)) { + const CallExpr *CE = cast(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()); } } 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