summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/ItaniumCXXABI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/ItaniumCXXABI.cpp')
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp13
1 files changed, 9 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 5c33f8c1afa..c1f892a3173 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -63,8 +63,11 @@ public:
bool classifyReturnType(CGFunctionInfo &FI) const override;
RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override {
- // If C++ prohibits us from making a copy, pass by address.
- if (!canCopyArgument(RD))
+ // Structures with either a non-trivial destructor or a non-trivial
+ // copy constructor are always indirect.
+ // FIXME: Use canCopyArgument() when it is fixed to handle lazily declared
+ // special members.
+ if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor())
return RAA_Indirect;
return RAA_Default;
}
@@ -1011,8 +1014,10 @@ bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
if (!RD)
return false;
- // If C++ prohibits us from making a copy, return by address.
- if (!canCopyArgument(RD)) {
+ // Return indirectly if we have a non-trivial copy ctor or non-trivial dtor.
+ // FIXME: Use canCopyArgument() when it is fixed to handle lazily declared
+ // special members.
+ if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor()) {
auto Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType());
FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
return true;
OpenPOWER on IntegriCloud