summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2018-04-01 21:04:30 +0000
committerJohn McCall <rjmccall@apple.com>2018-04-01 21:04:30 +0000
commit4fcd9ef6736ebc9bd1cd2c7192579c469a54b958 (patch)
tree9a32b0881bf884f8d29c23124cd8c3a60319ff15
parentba8033be4d422fea1a4117238038197f8db56469 (diff)
downloadbcm5719-llvm-4fcd9ef6736ebc9bd1cd2c7192579c469a54b958.tar.gz
bcm5719-llvm-4fcd9ef6736ebc9bd1cd2c7192579c469a54b958.zip
Fix a major swiftcall ABI bug with trivial C++ class types.
The problem with the previous logic was that there might not be any explicit copy/move constructor declarations, e.g. if the type is trivial and we've never type-checked a copy of it. Relying on Sema's computation seems much more reliable. Also, I believe Richard's recommendation is exactly the rule we use now on the Itanium ABI, modulo the trivial_abi attribute (which this change of course fixes our handling of in Swift). This does mean that we have a less portable rule for deciding indirectness for swiftcall. I would prefer it if we just applied the Itanium rule universally under swiftcall, but in the meantime, I need to fix this bug. This only arises when defining functions with class-type arguments in C++, as we do in the Swift runtime. It doesn't affect normal Swift operation because we don't import code as C++. llvm-svn: 328942
-rw-r--r--clang/lib/CodeGen/SwiftCallingConv.cpp20
-rw-r--r--clang/test/CodeGenCXX/arm-swiftcall.cpp10
2 files changed, 14 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/SwiftCallingConv.cpp b/clang/lib/CodeGen/SwiftCallingConv.cpp
index 2a12078e198..7dc2a1d089d 100644
--- a/clang/lib/CodeGen/SwiftCallingConv.cpp
+++ b/clang/lib/CodeGen/SwiftCallingConv.cpp
@@ -742,22 +742,10 @@ void swiftcall::legalizeVectorType(CodeGenModule &CGM, CharUnits origVectorSize,
bool swiftcall::shouldPassCXXRecordIndirectly(CodeGenModule &CGM,
const CXXRecordDecl *record) {
- // Following a recommendation from Richard Smith, pass a C++ type
- // indirectly only if the destructor is non-trivial or *all* of the
- // copy/move constructors are deleted or non-trivial.
-
- if (record->hasNonTrivialDestructor())
- return true;
-
- // It would be nice if this were summarized on the CXXRecordDecl.
- for (auto ctor : record->ctors()) {
- if (ctor->isCopyOrMoveConstructor() && !ctor->isDeleted() &&
- ctor->isTrivial()) {
- return false;
- }
- }
-
- return true;
+ // FIXME: should we not rely on the standard computation in Sema, just in
+ // case we want to diverge from the platform ABI (e.g. on targets where
+ // that uses the MSVC rule)?
+ return !record->canPassInRegisters();
}
static ABIArgInfo classifyExpandedType(SwiftAggLowering &lowering,
diff --git a/clang/test/CodeGenCXX/arm-swiftcall.cpp b/clang/test/CodeGenCXX/arm-swiftcall.cpp
index 5c932c77b1d..36a5afad4c6 100644
--- a/clang/test/CodeGenCXX/arm-swiftcall.cpp
+++ b/clang/test/CodeGenCXX/arm-swiftcall.cpp
@@ -113,3 +113,13 @@ TEST(struct_indirect_1)
// Should not be byval.
// CHECK-LABEL: define {{.*}} void @take_struct_indirect_1({{.*}}*{{( %.*)?}})
+
+// Do a simple standalone test here of a function definition to ensure that
+// we don't have problems due to failure to eagerly synthesize a copy
+// constructor declaration.
+class struct_trivial {
+ int x;
+};
+// CHECK-LABEL define void @test_struct_trivial(i32{{( %.*)?}})
+extern "C" SWIFTCALL
+void test_struct_trivial(struct_trivial triv) {}
OpenPOWER on IntegriCloud