summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGCXXABI.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-08-08 19:12:28 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-08-08 19:12:28 +0000
commit34b5db131b474135574bd12643339a8974077a38 (patch)
treea63676813c02d003f17e48ab254454d10060ca99 /lib/CodeGen/CGCXXABI.cpp
parent89be37b467850bf7c86dfe227352f09721092385 (diff)
PR19668, PR23034: Fix handling of move constructors and deleted copy
constructors when deciding whether classes should be passed indirectly. This fixes ABI differences between Clang and GCC: * Previously, Clang ignored the move constructor when making this determination. It now takes the move constructor into account, per https://github.com/itanium-cxx-abi/cxx-abi/pull/17 (this change may seem recent, but the ABI change was agreed on the Itanium C++ ABI list a long time ago). * Previously, Clang's behavior when the copy constructor was deleted was unstable -- depending on whether the lazy declaration of the copy constructor had been triggered, you might get different behavior. We now eagerly declare the copy constructor whenever its deletedness is unclear, and ignore deleted copy/move constructors when looking for a trivial such constructor. This also fixes an ABI difference between Clang and MSVC: * If the copy constructor would be implicitly deleted (but has not been lazily declared yet), for instance because the class has an rvalue reference member, we would pass it directly. We now pass such a class indirectly, matching MSVC. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@310401 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXXABI.cpp')
-rw-r--r--lib/CodeGen/CGCXXABI.cpp31
1 files changed, 1 insertions, 30 deletions
diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp
index e29e525edd..033258643d 100644
--- a/lib/CodeGen/CGCXXABI.cpp
+++ b/lib/CodeGen/CGCXXABI.cpp
@@ -30,38 +30,9 @@ void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) {
}
bool CGCXXABI::canCopyArgument(const CXXRecordDecl *RD) const {
- // If RD has a non-trivial move or copy constructor, we cannot copy the
- // argument.
- if (RD->hasNonTrivialCopyConstructor() || RD->hasNonTrivialMoveConstructor())
- return false;
-
- // If RD has a non-trivial destructor, we cannot copy the argument.
- if (RD->hasNonTrivialDestructor())
- return false;
-
// We can only copy the argument if there exists at least one trivial,
// non-deleted copy or move constructor.
- // FIXME: This assumes that all lazily declared copy and move constructors are
- // not deleted. This assumption might not be true in some corner cases.
- bool CopyDeleted = false;
- bool MoveDeleted = false;
- for (const CXXConstructorDecl *CD : RD->ctors()) {
- if (CD->isCopyConstructor() || CD->isMoveConstructor()) {
- assert(CD->isTrivial());
- // We had at least one undeleted trivial copy or move ctor. Return
- // directly.
- if (!CD->isDeleted())
- return true;
- if (CD->isCopyConstructor())
- CopyDeleted = true;
- else
- MoveDeleted = true;
- }
- }
-
- // If all trivial copy and move constructors are deleted, we cannot copy the
- // argument.
- return !(CopyDeleted && MoveDeleted);
+ return RD->canPassInRegisters();
}
llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) {