-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[cxx-interop] Fix calling convention for rvalue reference params #79576
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,11 @@ module Reference { | |
requires cplusplus | ||
} | ||
|
||
module SpecialMembers { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: why is this module case called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In C++ we call move/copy constructors special member functions: https://en.wikipedia.org/wiki/Special_member_functions |
||
header "print-special-members.h" | ||
requires cplusplus | ||
} | ||
|
||
module Closures { | ||
header "closures.h" | ||
requires cplusplus | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#pragma once | ||
#include <cstdio> | ||
|
||
struct MoveOnly { | ||
int id; | ||
MoveOnly() : id(0) { printf("MoveOnly %d created\n", id); } | ||
MoveOnly(const MoveOnly&) = delete; | ||
MoveOnly(MoveOnly&& other) : id(other.id + 1) { printf("MoveOnly %d move-created\n", id); } | ||
~MoveOnly() { printf("MoveOnly %d destroyed\n", id); } | ||
}; | ||
|
||
struct Copyable { | ||
int id; | ||
Copyable() : id(0) { printf("Copyable %d created\n", id); } | ||
Copyable(const Copyable& other) : id(other.id + 1) { printf("Copyable %d copy-created\n", id); } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is/can this copy constructor invoked when we do something like: let c0 = Copyable()
let c1 = Copyable(c0) // or should it be Copyable(other: c0)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, we do not import the copy constructor as an initializer into Swift. Users cannot invoke them directly. |
||
Copyable(Copyable&& other) : id(other.id + 1) { printf("Copyable %d move-created\n", id); } | ||
~Copyable() { printf("Copyable %d destroyed\n", id); } | ||
}; | ||
|
||
inline void byRValueRef(MoveOnly&& x) {} | ||
inline void byRValueRef(Copyable&& x) {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-experimental-cxx-interop -Onone) | %FileCheck -check-prefix=CHECK-DASH-ONONE %s | ||
// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-experimental-cxx-interop -O) | %FileCheck -check-prefix=CHECK-DASH-O %s | ||
// | ||
// REQUIRES: executable_test | ||
|
||
import SpecialMembers | ||
|
||
func consume(_ x: consuming MoveOnly) {} | ||
func consume(_ x: consuming Copyable) {} | ||
|
||
func moveOnly1() { | ||
let x = MoveOnly() | ||
// CHECK-DASH-ONONE: MoveOnly 0 created | ||
// CHECK-DASH-O: MoveOnly 0 created | ||
byRValueRef(consuming: x) | ||
// CHECK-DASH-ONONE-NEXT: MoveOnly 1 move-created | ||
// CHECK-DASH-O-NEXT: MoveOnly 1 move-created | ||
// CHECK-DASH-ONONE-NEXT: MoveOnly 0 destroyed | ||
// CHECK-DASH-O-NEXT: MoveOnly 0 destroyed | ||
// CHECK-DASH-ONONE-NEXT: MoveOnly 1 destroyed | ||
// CHECK-DASH-O-NEXT: MoveOnly 1 destroyed | ||
} | ||
|
||
func moveOnly2() { | ||
let x = MoveOnly() | ||
// CHECK-DASH-ONONE-NEXT: MoveOnly 0 created | ||
// CHECK-DASH-O-NEXT: MoveOnly 0 created | ||
consume(x) | ||
// CHECK-DASH-ONONE-NEXT: MoveOnly 1 move-created | ||
// CHECK-DASH-ONONE-NEXT: MoveOnly 0 destroyed | ||
// CHECK-DASH-O-NEXT: MoveOnly 0 destroyed | ||
// CHECK-DASH-ONONE-NEXT: MoveOnly 2 move-created | ||
// CHECK-DASH-ONONE-NEXT: MoveOnly 1 destroyed | ||
// CHECK-DASH-ONONE-NEXT: MoveOnly 2 destroyed | ||
} | ||
|
||
func copyable1() { | ||
let x = Copyable() | ||
// CHECK-DASH-ONONE-NEXT: Copyable 0 created | ||
// CHECK-DASH-O-NEXT: Copyable 0 created | ||
byRValueRef(consuming: x) | ||
// CHECK-DASH-ONONE-NEXT: Copyable 1 copy-created | ||
// CHECK-DASH-O-NEXT: Copyable 1 copy-created | ||
// CHECK-DASH-ONONE-NEXT: Copyable 1 destroyed | ||
// CHECK-DASH-O-NEXT: Copyable 1 destroyed | ||
// CHECK-DASH-ONONE-NEXT: Copyable 0 destroyed | ||
// CHECK-DASH-O-NEXT: Copyable 0 destroyed | ||
} | ||
|
||
func copyable2() { | ||
let x4 = Copyable() | ||
// CHECK-DASH-ONONE-NEXT: Copyable 0 created | ||
// CHECK-DASH-O-NEXT: Copyable 0 created | ||
consume(x4) | ||
// CHECK-DASH-ONONE-NEXT: Copyable 1 copy-created | ||
// CHECK-DASH-ONONE-NEXT: Copyable 2 move-created | ||
// CHECK-DASH-ONONE-NEXT: Copyable 1 destroyed | ||
// CHECK-DASH-ONONE-NEXT: Copyable 2 destroyed | ||
// CHECK-DASH-ONONE-NEXT: Copyable 0 destroyed | ||
// CHECK-DASH-O-NEXT: Copyable 0 destroyed | ||
} | ||
|
||
func main() { | ||
moveOnly1() | ||
moveOnly2() | ||
copyable1() | ||
copyable2() | ||
} | ||
|
||
main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to help me better understand this patch, because I don't see this case being defined in this patch, and the
default
case isllvm_unreachable
.Does this mean that the
Indirect_In_Cxx
case was not possible prior to this patch? (I'm guessing it's the additions tolib/SIL/IR/SILFunctionType.cpp
that make this case possible?)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hit the unreachable assertion with the test case I added. My suspicion is that it was possible to trigger this even before my patch we just did not run into it with an assertions enabled compiler.