diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-11-13 23:16:33 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-11-13 23:16:33 +0000 |
commit | 25f071eedf5d20faf9e1614d5ff5dc39b6de5041 (patch) | |
tree | 9f973a73dc0d940981bf71444d63f41bfcac0e4d /lib/Sema/SemaPseudoObject.cpp | |
parent | 0a26d7680d064653cb42e89e70c62402283003fd (diff) |
Don't try to save the assigned value in a Objective-C property assignment
if the type of the value is a non-trivial class type. Fixes PR14318.
(There's a minor ObjC++ language change here: given that we can't save the
value, the type of the assignment expression is void in such cases.)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167884 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaPseudoObject.cpp')
-rw-r--r-- | lib/Sema/SemaPseudoObject.cpp | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp index 37d9e77548..a8d75b290f 100644 --- a/lib/Sema/SemaPseudoObject.cpp +++ b/lib/Sema/SemaPseudoObject.cpp @@ -198,7 +198,14 @@ namespace { } /// Return true if assignments have a non-void result. - virtual bool assignmentsHaveResult() { return true; } + bool CanCaptureValueOfType(QualType ty) { + assert(!ty->isIncompleteType()); + assert(!ty->isDependentType()); + + if (const CXXRecordDecl *ClassDecl = ty->getAsCXXRecordDecl()) + return ClassDecl->isTriviallyCopyable(); + return true; + } virtual Expr *rebuildAndCaptureObject(Expr *) = 0; virtual ExprResult buildGet() = 0; @@ -380,7 +387,7 @@ PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc, // The result of the assignment, if not void, is the value set into // the l-value. - result = buildSet(result.take(), opcLoc, assignmentsHaveResult()); + result = buildSet(result.take(), opcLoc, /*captureSetValueAsResult*/ true); if (result.isInvalid()) return ExprError(); addSemanticExpr(result.take()); @@ -404,7 +411,7 @@ PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, QualType resultType = result.get()->getType(); // That's the postfix result. - if (UnaryOperator::isPostfix(opcode) && assignmentsHaveResult()) { + if (UnaryOperator::isPostfix(opcode) && CanCaptureValueOfType(resultType)) { result = capture(result.take()); setResultToLastSemantic(); } @@ -423,8 +430,7 @@ PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, // Store that back into the result. The value stored is the result // of a prefix operation. - result = buildSet(result.take(), opcLoc, - UnaryOperator::isPrefix(opcode) && assignmentsHaveResult()); + result = buildSet(result.take(), opcLoc, UnaryOperator::isPrefix(opcode)); if (result.isInvalid()) return ExprError(); addSemanticExpr(result.take()); @@ -696,7 +702,8 @@ ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, ObjCMessageExpr *msgExpr = cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit()); Expr *arg = msgExpr->getArg(0); - msgExpr->setArg(0, captureValueAsResult(arg)); + if (CanCaptureValueOfType(arg->getType())) + msgExpr->setArg(0, captureValueAsResult(arg)); } return msg; @@ -1312,7 +1319,8 @@ ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, ObjCMessageExpr *msgExpr = cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit()); Expr *arg = msgExpr->getArg(0); - msgExpr->setArg(0, captureValueAsResult(arg)); + if (CanCaptureValueOfType(arg->getType())) + msgExpr->setArg(0, captureValueAsResult(arg)); } return msg; |