summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp15
1 files changed, 10 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 4428b963162..da504739836 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2289,20 +2289,25 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
if (HasAggregateEvalKind &&
CGM.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
// If we're using inalloca, use the argument memory. Otherwise, use a
- // temporary. Either way, the aggregate is destroyed externally in the
- // callee.
+ // temporary.
AggValueSlot Slot;
if (args.isUsingInAlloca())
Slot = createPlaceholderSlot(*this, type);
else
Slot = CreateAggTemp(type, "agg.tmp");
- Slot.setExternallyDestructed();
+
+ const CXXRecordDecl *RD = type->getAsCXXRecordDecl();
+ bool DestroyedInCallee =
+ RD && RD->hasNonTrivialDestructor() &&
+ CGM.getCXXABI().getRecordArgABI(RD) != CGCXXABI::RAA_Default;
+ if (DestroyedInCallee)
+ Slot.setExternallyDestructed();
+
EmitAggExpr(E, Slot);
RValue RV = Slot.asRValue();
args.add(RV, type);
- const CXXRecordDecl *RD = type->getAsCXXRecordDecl();
- if (RD && RD->hasNonTrivialDestructor()) {
+ if (DestroyedInCallee) {
// Create a no-op GEP between the placeholder and the cleanup so we can
// RAUW it successfully. It also serves as a marker of the first
// instruction where the cleanup is active.
OpenPOWER on IntegriCloud