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

llvm-svn: 141302
This commit is contained in:
Fariborz Jahanian 2011-10-06 18:38:18 +00:00
parent a9455ec9f8
commit 565ed7a4c1
4 changed files with 48 additions and 1 deletions

View 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">,

View 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>());
}
}

View 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

View 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