Skip to content

[Swift bridging] Consistently use correctly-defined Swift(U)Int for bridging #68278

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

Merged
merged 7 commits into from
Sep 2, 2023

Conversation

DougGregor
Copy link
Member

The SwiftInt and SwiftUInt types in the compiler provide C equivalents to Swift's Int and UInt. Consistently use these types in the C/Swift bridging layer, to avoid painful truncations and data-size mismatches.

This is harder than it should be. The canonical C types are ptrdiff_t and size_t, but we're in the depths of the compiler we can't include the C library headers that provide them because they introduce cyclic module dependencies. Sigh.

SwiftShims has some logic to compute these types. However, SwiftShims is part of the Swift runtime, not the compiler, so those headers cannot be included here. So, we clone the logic and simplify it somewhat for our use case.

This fixes truncation issues on Windows, where the uses of unsigned long and long for Swift(U)Int are incorrect.

The C type tha corresponds to Swift's pointer-sized `Int` and `UInt`
types varies from one platform to the next. The canonical C types are
`ptrdiff_t` and `size_t`, but we're in the depths of the compiler we
can't include the C library headers that provide them because they
introduce cyclic module dependencies. Sigh.

SwiftShims has some logic to compute these types. However, SwiftShims
is part of the Swift runtime, not the compiler, so those headers
cannot be included here. So, we clone the logic and simplify it
somewhat for our use case.

This fixes truncation issues on Windows, where the uses of
`unsigned long` and `long` for Swift(U)Int are incorrect.
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

…t/UInt

64-bit Windows defines both _WIN64 and _WIN32, so the logic here would
always end up defining 32-bit C types for Swift's `Int` and `UInt`.
Fix the ordering to check for 64-bit first, then 32-bit second.

Note that the SwiftShims version of this code has always been wrong,
but it's completely benign because SwiftShims is only used in the
Swift runtime itself, which is built with Clang (on all platforms),
and doesn't need to go through this code path. Still, we fix it in both
places, so we don't get a nasty surprise if the SwiftShims version of
the header later gets included in a non-Clang C++ compiler.
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

Copy link
Member

@compnerd compnerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Thanks again @DougGregor!

@DougGregor
Copy link
Member Author

@swift-ci please smoke test

Co-authored-by: Saleem Abdulrasool <[email protected]>
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

Co-authored-by: Saleem Abdulrasool <[email protected]>
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

The type definitions do not uniformly import as `Swift.Int` and `Swift.UInt`.  Add some casts to accommodate the type conversions.
@compnerd
Copy link
Member

compnerd commented Sep 2, 2023

@swift-ci please smoke test

@DougGregor DougGregor merged commit 3e4dd43 into swiftlang:main Sep 2, 2023
@DougGregor DougGregor deleted the swift-int-type-bridging branch September 2, 2023 06:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants