Skip to content

[cxx-interop] Itanium ABI C++ records should have address-only layout when they can't be passed in registers#66694

Merged
hyp merged 4 commits intoswiftlang:release/5.9from
hyp:eng/5.9/61929
Jun 16, 2023
Merged

[cxx-interop] Itanium ABI C++ records should have address-only layout when they can't be passed in registers#66694
hyp merged 4 commits intoswiftlang:release/5.9from
hyp:eng/5.9/61929

Conversation

@hyp
Copy link
Contributor

@hyp hyp commented Jun 16, 2023

This ensures that a C++ record with only ObjC ARC pointers with trivial other members is passed by value in SIL.
Fixes #61929

Additionally, mark C++ classes with trivial_abi attribute as unavailable in Swift.

  • Explanation:
    Non-trivial C++ records become AddressOnly Swift structures, as that's the only way to guarantee the invocation of their copy and/or destroy operations from Swift. AddressOnly implies indirect parameter passing as well. However, under Itanium ABI, some C++ records that have only ARC pointers can be passed directly even though they're non-trivial types. This causes a runtime crash as we think such C++ records are passed indirectly instead from Swift.

This change modifies the way we decide which records become AddressOnly Swift structs on Itanium ABI, by using Clang's own mechanism that determines if the record can be passed in registers or not. This largely aligns the semantics of C++'s indirect + non-trivial copy/destroy with Swift's AddressOnly semantics, except for C++ records annotated with trivial_abi. Such types are now marked as unavailable in Swift instead, as they can't be supported yet in the current implementation.

On Windows for the MSVC target the situation is more complicated, and this patch leaves the current behavior instead. The problem is that the MSVC ABI allows non-trivially destroyed but trivially copyable C++ records to be passed in registers. This can't be supported without AddressOnly in Swift, as we wouldn't be able to destroy such C++ record correctly. Thus, for now, preserve the existing behavior. A follow-up future fix will need to teach Swift's code generator how to pass AddressOnly C++ records directly to fix both the MSVC ABI and to support trivial_abi for Itanium as well.

hyp and others added 4 commits June 15, 2023 18:35
…an't be passed in registers

This ensures that a C++ record with only ObjC ARC pointers with trivial other members is passed by value in SIL

Fixes swiftlang#61929

(cherry picked from commit decd21f)
@hyp hyp added c++ interop Feature: Interoperability with C++ swift 5.9 labels Jun 16, 2023
@hyp hyp requested a review from a team as a code owner June 16, 2023 01:46
@hyp
Copy link
Contributor Author

hyp commented Jun 16, 2023

@swift-ci please test

@hyp
Copy link
Contributor Author

hyp commented Jun 16, 2023

@swift-ci please test source compatibility

@hyp hyp merged commit 159b05d into swiftlang:release/5.9 Jun 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ interop Feature: Interoperability with C++ swift 5.9

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants