]> granicus.if.org Git - clang/commitdiff
objc++: For atomic properties of c++ class objec typet, appropriate
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 6 Oct 2011 18:38:18 +0000 (18:38 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 6 Oct 2011 18:38:18 +0000 (18:38 +0000)
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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaObjCProperty.cpp
test/SemaObjCXX/property-reference.mm
test/SemaObjCXX/property-synthesis-error.mm

index fc8c636bb3f4842e2f4bd3eb50e695984f01060f..d4c118b447b20ca598b9f83ad4e4a5dd7eabb922 100644 (file)
@@ -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">,
index 880e9bfb2b27b2749ff70af7ce7a8158d1720bf1..5a54f575805b98ec13ca84c3ba797889874099fa 100644 (file)
@@ -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>());
     }
   }
index 11818d575a71b37b096f569a270ee3f0995598dd..98bc7273001f432f374ca9b5edc972a6eeee627f 100644 (file)
@@ -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
index c67f0a45c74d0a3c034ab0500381c6f260c12a37..f79a56db6cd0ed913cd72a826db94450367b84d9 100644 (file)
@@ -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