summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-09-27 23:44:22 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-09-27 23:44:22 +0000
commit97a616d6244791b2fe36805e673b2f1a26985609 (patch)
tree7bc539937a5845d5077923f876c167e517ff87a2 /clang/lib/CodeGen/CGExpr.cpp
parent3d1235a97d805e00222f12dc11dfac83b9164551 (diff)
downloadbcm5719-llvm-97a616d6244791b2fe36805e673b2f1a26985609.tar.gz
bcm5719-llvm-97a616d6244791b2fe36805e673b2f1a26985609.zip
P0145R3 (C++17 evaluation order tweaks): evaluate the right-hand side of
assignment and compound-assignment operators before the left-hand side. (Even if it's an overloaded operator.) This completes the implementation of P0145R3 + P0400R0 for all targets except Windows, where the evaluation order guarantees for <<, >>, and ->* are unimplementable as the ABI requires the function arguments are evaluated from right to left (because parameter destructors are run from left to right in the callee). llvm-svn: 282556
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp11
1 files changed, 10 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index bca711fbc8c..63aa3467850 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4121,8 +4121,17 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
if (Chain)
Args.add(RValue::get(Builder.CreateBitCast(Chain, CGM.VoidPtrTy)),
CGM.getContext().VoidPtrTy);
+
+ // C++17 requires that we evaluate arguments to a call using assignment syntax
+ // right-to-left. It also requires that we evaluate arguments to operators
+ // <<, >>, and ->* left-to-right, but that is not possible under the MS ABI,
+ // so there is no corresponding "force left-to-right" case.
+ bool ForceRightToLeft = false;
+ if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(E))
+ ForceRightToLeft = OCE->isAssignmentOp();
+
EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), E->arguments(),
- E->getDirectCallee(), /*ParamsToSkip*/ 0);
+ E->getDirectCallee(), /*ParamsToSkip*/ 0, ForceRightToLeft);
const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeFreeFunctionCall(
Args, FnType, /*isChainCall=*/Chain);
OpenPOWER on IntegriCloud