summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-09-29 21:30:12 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-09-29 21:30:12 +0000
commita560ccf2af7a19eeb065d0d8869f7b9378f6d1ff (patch)
tree3d1c3cfca87c948d4936b630430f4709ee0ccc0f /clang/lib/CodeGen/CGExpr.cpp
parentb1b9546b36ba5eab93f40ccf44ebe537375823ae (diff)
downloadbcm5719-llvm-a560ccf2af7a19eeb065d0d8869f7b9378f6d1ff.tar.gz
bcm5719-llvm-a560ccf2af7a19eeb065d0d8869f7b9378f6d1ff.zip
Switch to a different workaround for unimplementability of P0145R3 in MS ABIs.
Instead of ignoring the evaluation order rule, ignore the "destroy parameters in reverse construction order" rule for the small number of problematic cases. This only causes incorrect behavior in the rare case where both parameters to an overloaded operator <<, >>, ->*, &&, ||, or comma are of class type with non-trivial destructor, and the program is depending on those parameters being destroyed in reverse construction order. We could do a little better here by reversing the order of parameter destruction for those functions (and reversing the argument evaluation order for all direct calls, not just those with operator syntax), but that is not a complete solution to the problem, as the same situation can be reached by an indirect function call. Approach reviewed off-line by rnk. llvm-svn: 282777
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp32
1 files changed, 25 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 63aa3467850..7e12f5e7358 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4123,15 +4123,33 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
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();
+ // right-to-left, and that we evaluate arguments to certain other operators
+ // left-to-right. Note that we allow this to override the order dictated by
+ // the calling convention on the MS ABI, which means that parameter
+ // destruction order is not necessarily reverse construction order.
+ // FIXME: Revisit this based on C++ committee response to unimplementability.
+ EvaluationOrder Order = EvaluationOrder::Default;
+ if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
+ if (OCE->isAssignmentOp())
+ Order = EvaluationOrder::ForceRightToLeft;
+ else {
+ switch (OCE->getOperator()) {
+ case OO_LessLess:
+ case OO_GreaterGreater:
+ case OO_AmpAmp:
+ case OO_PipePipe:
+ case OO_Comma:
+ case OO_ArrowStar:
+ Order = EvaluationOrder::ForceLeftToRight;
+ break;
+ default:
+ break;
+ }
+ }
+ }
EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), E->arguments(),
- E->getDirectCallee(), /*ParamsToSkip*/ 0, ForceRightToLeft);
+ E->getDirectCallee(), /*ParamsToSkip*/ 0, Order);
const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeFreeFunctionCall(
Args, FnType, /*isChainCall=*/Chain);
OpenPOWER on IntegriCloud