Skip to content

Commit a13940f

Browse files
author
Gabor Horvath
committed
[cxx-interop] Do not generate aborting move constructors
In the reverse interop header we generated move constructors that call abort at runtime. This is problematic for several reasons: * In C++14 and below some of our own generated functions like _make ended up calling the move constructor. Those are calling abort and also trigger unreachable code warning in newer versions of Clang. In C++17 and up it is fine due to the guaranteed copy elision. * Type traits are fooled and think these types are movable. As a result, libraries could generate calls to the aborting move ctor. This PR removes the generation of move operations. As we generate copy operations, the compiler will not declare or define the move operations implicitly. Whenever the user goes out of their way and try to move an object they will get a copy instead. rdar://150793518
1 parent 31408fe commit a13940f

File tree

11 files changed

+15
-68
lines changed

11 files changed

+15
-68
lines changed

lib/PrintAsClang/PrintClangValueType.cpp

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -330,33 +330,7 @@ void ClangValueTypePrinter::printValueTypeDecl(
330330
os << " }\n";
331331

332332
// FIXME: implement the move assignment.
333-
os << " ";
334-
printer.printInlineForThunk();
335-
printer.printBaseName(typeDecl);
336-
os << " &operator =(";
337-
printer.printBaseName(typeDecl);
338-
os << " &&other) = delete;\n";
339-
340333
// FIXME: implement the move constructor.
341-
os << " [[noreturn]] ";
342-
// NOTE: Do not apply attribute((used))
343-
// here to ensure the linker error isn't
344-
// forced, so just mark this an inline
345-
// helper function instead.
346-
printer.printInlineForHelperFunction();
347-
printer.printBaseName(typeDecl);
348-
os << "(";
349-
printer.printBaseName(typeDecl);
350-
StringRef moveErrorMessage =
351-
"C++ does not support moving a Swift value yet";
352-
os << " &&) noexcept {\n "
353-
"swift::_impl::_fatalError_Cxx_move_of_Swift_value_type_not_"
354-
"supported_"
355-
"yet();\n swift::_impl::_swift_stdlib_reportFatalError(\"swift\", "
356-
"5, "
357-
"\""
358-
<< moveErrorMessage << "\", " << moveErrorMessage.size()
359-
<< ", 0);\n abort();\n }\n";
360334

361335
bodyPrinter();
362336
if (typeDecl->isStdlibDecl())

test/Interop/SwiftToCxx/expose-attr/expose-swift-decls-to-cxx.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public final class ExposedClass {
8282
// CHECK: class SWIFT_SYMBOL("{{.*}}") ExposedClass final
8383
// CHECK: class SWIFT_SYMBOL("{{.*}}") ExposedStruct final {
8484
// CHECK: class SWIFT_SYMBOL("{{.*}}") ExposedStruct2 final {
85-
// CHECK: ExposedStruct2(ExposedStruct2 &&)
85+
// CHECK: SWIFT_INLINE_THUNK ExposedStruct2 &operator =(const ExposedStruct2 &other) noexcept {
8686
// CHECK: }
8787
// CHECK-NEXT: swift::Int getY() const SWIFT_SYMBOL("{{.*}}");
8888
// CHECK-NEXT: void setY(swift::Int value) SWIFT_SYMBOL("{{.*}}");

test/Interop/SwiftToCxx/initializers/init-in-cxx.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public struct FirstSmallStruct {
3939

4040
// CHECK: class SWIFT_SYMBOL("s:4Init16FirstSmallStructV") FirstSmallStruct final {
4141
// CHECK-NEXT: public:
42-
// CHECK: SWIFT_INLINE_PRIVATE_HELPER FirstSmallStruct(FirstSmallStruct &&)
42+
// CHECK: SWIFT_INLINE_THUNK FirstSmallStruct &operator =(const FirstSmallStruct &other) noexcept {
4343
// CHECK: }
4444
// CHECK-NEXT: SWIFT_INLINE_THUNK uint32_t getX() const SWIFT_SYMBOL("s:4Init16FirstSmallStructV1xs6UInt32Vvp");
4545
// CHECK-NEXT: static SWIFT_INLINE_THUNK FirstSmallStruct init() SWIFT_SYMBOL("s:4Init16FirstSmallStructVACycfc");

test/Interop/SwiftToCxx/methods/method-in-cxx.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public final class PassStructInClassMethod {
105105
// CHECK-NEXT: static SWIFT_INLINE_THUNK LargeStruct staticFinalClassMethod(swift::Int x) SWIFT_SYMBOL("s:7Methods09ClassWithA0C011staticFinalB6Method1xAA11LargeStructVSi_tFZ");
106106

107107
// CHECK: class SWIFT_SYMBOL("s:7Methods11LargeStructV") LargeStruct final {
108-
// CHECK: SWIFT_INLINE_PRIVATE_HELPER LargeStruct(LargeStruct &&)
108+
// CHECK: SWIFT_INLINE_THUNK LargeStruct &operator =(const LargeStruct &other) noexcept {
109109
// CHECK: }
110110
// CHECK-NEXT: SWIFT_INLINE_THUNK LargeStruct doubled() const SWIFT_SYMBOL("s:7Methods11LargeStructV7doubledACyF");
111111
// CHECK-NEXT: SWIFT_INLINE_THUNK void dump() const SWIFT_SYMBOL("s:7Methods11LargeStructV4dumpyyF");

test/Interop/SwiftToCxx/methods/mutating-method-in-cxx.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ public struct SmallStruct {
5757
// CHECK: SWIFT_EXTERN void $s7Methods11SmallStructV6invertyyF(SWIFT_CONTEXT void * _Nonnull _self) SWIFT_NOEXCEPT SWIFT_CALL; // invert()
5858

5959
// CHECK: class SWIFT_SYMBOL("s:7Methods11LargeStructV") LargeStruct final {
60-
// CHECK: SWIFT_INLINE_PRIVATE_HELPER LargeStruct(LargeStruct &&)
60+
// CHECK: SWIFT_INLINE_THUNK LargeStruct &operator =(const LargeStruct &other) noexcept {
6161
// CHECK: }
6262
// CHECK-NEXT: SWIFT_INLINE_THUNK void dump() const SWIFT_SYMBOL("s:7Methods11LargeStructV4dumpyyF");
6363
// CHECK-NEXT: SWIFT_INLINE_THUNK void double_() SWIFT_SYMBOL("s:7Methods11LargeStructV6doubleyyF");
6464
// CHECK-NEXT: SWIFT_INLINE_THUNK LargeStruct scale(swift::Int x, swift::Int y) SWIFT_SYMBOL("s:7Methods11LargeStructV5scaleyACSi_SitF");
6565
// CHECK-NEXT: private
6666

6767
// CHECK: class SWIFT_SYMBOL("s:7Methods11SmallStructV") SmallStruct final {
68-
// CHECK: SWIFT_INLINE_PRIVATE_HELPER SmallStruct(SmallStruct &&)
68+
// CHECK: SWIFT_INLINE_THUNK SmallStruct &operator =(const SmallStruct &other) noexcept {
6969
// CHECK: }
7070
// CHECK-NEXT: SWIFT_INLINE_THUNK void dump() const SWIFT_SYMBOL("s:7Methods11SmallStructV4dumpyyF");
7171
// CHECK-NEXT: SWIFT_INLINE_THUNK SmallStruct scale(float y) SWIFT_SYMBOL("s:7Methods11SmallStructV5scaleyACSfF");

test/Interop/SwiftToCxx/properties/getter-in-cxx.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public struct FirstSmallStruct {
1010

1111
// CHECK: class SWIFT_SYMBOL({{.*}}) FirstSmallStruct final {
1212
// CHECK: public:
13-
// CHECK: SWIFT_INLINE_PRIVATE_HELPER FirstSmallStruct(FirstSmallStruct &&)
13+
// CHECK: SWIFT_INLINE_THUNK FirstSmallStruct &operator =(const FirstSmallStruct &other) noexcept {
1414
// CHECK: }
1515
// CHECK-NEXT: SWIFT_INLINE_THUNK uint32_t getX() const SWIFT_SYMBOL({{.*}});
1616
// CHECK-NEXT: private:
@@ -37,7 +37,7 @@ public struct LargeStruct {
3737

3838
// CHECK: class SWIFT_SYMBOL({{.*}}) LargeStruct final {
3939
// CHECK: public:
40-
// CHECK: SWIFT_INLINE_PRIVATE_HELPER LargeStruct(LargeStruct &&)
40+
// CHECK: SWIFT_INLINE_THUNK LargeStruct &operator =(const LargeStruct &other) noexcept {
4141
// CHECK: }
4242
// CHECK-NEXT: SWIFT_INLINE_THUNK swift::Int getX1() const SWIFT_SYMBOL({{.*}});
4343
// CHECK-NEXT: SWIFT_INLINE_THUNK swift::Int getX2() const SWIFT_SYMBOL({{.*}});
@@ -94,7 +94,7 @@ public struct SmallStructWithGetters {
9494

9595
// CHECK: class SWIFT_SYMBOL({{.*}}) SmallStructWithGetters final {
9696
// CHECK: public:
97-
// CHECK: SWIFT_INLINE_PRIVATE_HELPER SmallStructWithGetters(SmallStructWithGetters &&)
97+
// CHECK: SWIFT_INLINE_THUNK SmallStructWithGetters &operator =(const SmallStructWithGetters &other) noexcept {
9898
// CHECK: }
9999
// CHECK-NEXT: SWIFT_INLINE_THUNK uint32_t getStoredInt() const SWIFT_SYMBOL({{.*}});
100100
// CHECK-NEXT: SWIFT_INLINE_THUNK swift::Int getComputedInt() const SWIFT_SYMBOL({{.*}});

test/Interop/SwiftToCxx/properties/setter-in-cxx.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public struct FirstSmallStruct {
1010

1111
// CHECK: class SWIFT_SYMBOL({{.*}}) FirstSmallStruct final {
1212
// CHECK: public:
13-
// CHECK: SWIFT_INLINE_PRIVATE_HELPER FirstSmallStruct(FirstSmallStruct &&)
13+
// CHECK: SWIFT_INLINE_THUNK FirstSmallStruct &operator =(const FirstSmallStruct &other) noexcept {
1414
// CHECK: }
1515
// CHECK-NEXT: SWIFT_INLINE_THUNK uint32_t getX() const SWIFT_SYMBOL({{.*}});
1616
// CHECK-NEXT: SWIFT_INLINE_THUNK void setX(uint32_t value) SWIFT_SYMBOL({{.*}});
@@ -32,7 +32,7 @@ public struct LargeStruct {
3232

3333
// CHECK: class SWIFT_SYMBOL({{.*}}) LargeStruct final {
3434
// CHECK: public:
35-
// CHECK: SWIFT_INLINE_PRIVATE_HELPER LargeStruct(LargeStruct &&)
35+
// CHECK: SWIFT_INLINE_THUNK LargeStruct &operator =(const LargeStruct &other) noexcept {
3636
// CHECK: }
3737
// CHECK-NEXT: SWIFT_INLINE_THUNK swift::Int getX1() const SWIFT_SYMBOL({{.*}});
3838
// CHECK-NEXT: SWIFT_INLINE_THUNK void setX1(swift::Int value) SWIFT_SYMBOL({{.*}});
@@ -111,7 +111,7 @@ public struct SmallStructWithProps {
111111

112112
// CHECK: class SWIFT_SYMBOL({{.*}}) SmallStructWithProps final {
113113
// CHECK: public:
114-
// CHECK: SWIFT_INLINE_PRIVATE_HELPER SmallStructWithProps(SmallStructWithProps &&)
114+
// CHECK: SWIFT_INLINE_THUNK SmallStructWithProps &operator =(const SmallStructWithProps &other) noexcept {
115115
// CHECK: }
116116
// CHECK-NEXT: SWIFT_INLINE_THUNK uint32_t getStoredInt() const SWIFT_SYMBOL({{.*}});
117117
// CHECK-NEXT: SWIFT_INLINE_THUNK void setStoredInt(uint32_t value) SWIFT_SYMBOL({{.*}});

test/Interop/SwiftToCxx/stdlib/swift-stdlib-in-cxx.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,6 @@
8181
// CHECK: }
8282
// CHECK-NEXT: SWIFT_INLINE_THUNK String &operator =(const String &other) noexcept {
8383
// CHECK: }
84-
// CHECK-NEXT: SWIFT_INLINE_THUNK String &operator =(String &&other) = delete;
85-
// CHECK-NEXT: SWIFT_INLINE_PRIVATE_HELPER String(String &&) noexcept {
86-
// CHECK: }
8784
// CHECK-NEXT: static SWIFT_INLINE_THUNK String init() SWIFT_SYMBOL({{.*}});
8885
// CHECK: SWIFT_INLINE_THUNK void append(const String& other)
8986
// CHECK: SWIFT_INLINE_THUNK __StringNested::UTF8View getUtf8() const SWIFT_SYMBOL({{.*}});
@@ -118,7 +115,7 @@
118115
// CHECK-NEXT: private:
119116

120117
// CHECK: class SWIFT_SYMBOL({{.*}}) UTF8View final {
121-
// CHECK: SWIFT_INLINE_PRIVATE_HELPER UTF8View(UTF8View &&) noexcept {
118+
// CHECK: SWIFT_INLINE_THUNK UTF8View &operator =(const UTF8View &other) noexcept {
122119
// CHECK: }
123120
// CHECK-NEXT: SWIFT_INLINE_THUNK __StringNested::Index getStartIndex() const SWIFT_SYMBOL({{.*}});
124121
// CHECK-NEXT: SWIFT_INLINE_THUNK __StringNested::Index getEndIndex() const SWIFT_SYMBOL({{.*}});

test/Interop/SwiftToCxx/structs/struct-move-semantics-in-cxx.cpp

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,47 +5,35 @@
55
// Link should fail by default when a move is
66
// performed in C++.
77
// RUN: %target-interop-build-clangxx -c %s -I %t -o %t/swift-structs-execution.o
8-
// RUN: not %target-interop-build-swift %S/large-structs-pass-return-indirect-in-cxx.swift -o %t/swift-structs-execution -Xlinker %t/swift-structs-execution.o -module-name Structs -Xfrontend -entry-point-function-name -Xfrontend swiftMain 2>&1 | %FileCheck --check-prefix=LINK %s
9-
10-
// LINK: fatalError_Cxx_move_of_Swift_value_type_not_supported_yet
8+
// RUN: %target-interop-build-swift %S/large-structs-pass-return-indirect-in-cxx.swift -o %t/swift-structs-execution -Xlinker %t/swift-structs-execution.o -module-name Structs -Xfrontend -entry-point-function-name -Xfrontend swiftMain 2>&1
119

1210
// Compile should fail by default when move assignment is attempted in C++:
1311

14-
// RUN: not %target-interop-build-clangxx -c %s -I %t -o %t/swift-structs-execution.o -DMOVE_ASSIGN 2>&1 | %FileCheck --check-prefix=MOVEASSIGN %s
12+
// RUN: %target-interop-build-clangxx -c %s -I %t -o %t/swift-structs-execution.o -DMOVE_ASSIGN 2>&1
1513

1614
// Fallback to abort at runtime:
1715

18-
// RUN: %target-interop-build-clangxx -c %s -I %t -o %t/swift-structs-execution.o -DLINKS
16+
// RUN: %target-interop-build-clangxx -c %s -I %t -o %t/swift-structs-execution.o
1917
// RUN: %target-interop-build-swift %S/large-structs-pass-return-indirect-in-cxx.swift -o %t/swift-structs-execution -Xlinker %t/swift-structs-execution.o -module-name Structs -Xfrontend -entry-point-function-name -Xfrontend swiftMain 2>&1
2018

2119
// RUN: %target-codesign %t/swift-structs-execution
2220
// RUN: %target-run %t/swift-structs-execution 2>%t/output || true
23-
// RUN: cat %t/output | %FileCheck %s
2421

2522
// REQUIRES: executable_test
2623

2724
#include <assert.h>
2825
#include "structs.h"
2926
#include <memory>
3027

31-
#ifdef LINKS
32-
extern "C" void _fatalError_Cxx_move_of_Swift_value_type_not_supported_yet() {
33-
34-
}
35-
#endif
36-
3728
int main() {
3829
using namespace Structs;
3930

4031
auto x = returnNewStructSeveralI64(42);
4132
#ifdef MOVE_ASSIGN
4233
auto y = returnNewStructSeveralI64(24);
4334
x = std::move(y);
44-
// MOVEASSIGN: deleted operator '='
4535
#else
4636
StructSeveralI64 x2 = std::move(x);
4737
#endif
4838
return 0;
4939
}
50-
51-
// CHECK: C++ does not support moving a Swift value yet

test/Interop/SwiftToCxx/structs/struct-with-refcounted-member.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,4 @@ public func printBreak(_ x: Int) {
5858
// CHECK-NEXT: vwTable->assignWithCopy(_getOpaquePointer(), const_cast<char *>(other._getOpaquePointer()), metadata._0);
5959
// CHECK-NEXT: return *this;
6060
// CHECK-NEXT: }
61-
// CHECK-NEXT: SWIFT_INLINE_THUNK StructWithRefcountedMember &operator =(StructWithRefcountedMember &&other) = delete;
62-
// CHECK-NEXT: SWIFT_INLINE_PRIVATE_HELPER StructWithRefcountedMember(StructWithRefcountedMember &&) noexcept {
63-
// CHECK-NEXT: swift::_impl::_fatalError_Cxx_move_of_Swift_value_type_not_supported_yet();
64-
// CHECK-NEXT: swift::_impl::_swift_stdlib_reportFatalError("swift", 5, "C++ does not support moving a Swift value yet", 45, 0);
65-
// CHECK-NEXT: abort();
66-
// CHECK-NEXT: }
6761
// CHECK-NEXT: private:

0 commit comments

Comments
 (0)