Skip to content

Fix ASTMangler mangling NS_OPTION differently in C++ mode #64043

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 1 commit into from
Mar 17, 2023

Conversation

NuriAmari
Copy link
Contributor

@NuriAmari NuriAmari commented Mar 2, 2023

CF_OPTIONS is defined differently in the SDK based on a __cplusplus preprocessor branch. As a result, declarations referencing CF_OPTIONS are mangled differently depending on if C++ interop is enabled.

This meant a module compiled with cxx interop on could not be linked with a module compiled without and vice versa. This patch modifies the mangler such that the mangled names are consistent. This is achieved by feeding the mangler a modified AST node that looks like the Objective-C definition of CF_OPTIONS, even when we have cxx interop enabled.

@NuriAmari NuriAmari force-pushed the ns-option-linkage-conflict branch from 7244342 to b5eb7b7 Compare March 2, 2023 22:47
// Use an anonymous enum's enclosing typedef for the mangled name, if
// present. This matches C++'s rules for linkage names of tag declarations.
if (namedDecl->getDeclName().isEmpty())
if (auto *tagDecl = dyn_cast<clang::TagDecl>(namedDecl))
if (auto *typedefDecl = tagDecl->getTypedefNameForAnonDecl())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a little weird. I want to make the Clang AST look like the Objective-C definition so that the mangled name will be the same, but I don't want the mutation to persist beyond after the mangler is done with it. More specifically, I want the anonymous enum to no longer be anonymous and instead have the backing typedef's name.

I considered making a copy of the node, but that seems pretty wasteful. I'd have to copy at least once per NS_OPTION use and keep them around somewhere. Instead I've made this RAII container that just clears the anonymous enum's name after the client is done with it.

@NuriAmari
Copy link
Contributor Author

@swift-ci Please test

@NuriAmari
Copy link
Contributor Author

@swift-ci Please test source compatibility suite

@NuriAmari
Copy link
Contributor Author

@swift-ci Please Test Source Compatibility

@NuriAmari NuriAmari requested review from plotfi and drodriguez March 2, 2023 23:06
@NuriAmari NuriAmari marked this pull request as ready for review March 2, 2023 23:09
@NuriAmari NuriAmari marked this pull request as draft March 2, 2023 23:29
@NuriAmari NuriAmari force-pushed the ns-option-linkage-conflict branch from b5eb7b7 to e3bf0ab Compare March 3, 2023 18:23
@NuriAmari
Copy link
Contributor Author

@swift-ci Please test

@NuriAmari
Copy link
Contributor Author

@swift-ci Please Test Source Compatibility

@xedin xedin removed their request for review March 3, 2023 23:17
@NuriAmari
Copy link
Contributor Author

@swift-ci Please test macOS platform

@NuriAmari
Copy link
Contributor Author

@swift-ci Please test Windows platform

@plotfi plotfi marked this pull request as ready for review March 5, 2023 22:18
@plotfi
Copy link
Contributor

plotfi commented Mar 5, 2023

LGTM. I will merge once we get a chance to chat about this 1:1 this week.

@NuriAmari NuriAmari force-pushed the ns-option-linkage-conflict branch from e3bf0ab to 6a6b4f6 Compare March 6, 2023 21:02
@NuriAmari
Copy link
Contributor Author

@swift-ci Please test

@NuriAmari
Copy link
Contributor Author

@swift-ci Please test source compatibility

@NuriAmari
Copy link
Contributor Author

Compat suite failures are unrelated. The change passed compat suite before, and I've only made non-functional changes since to address PR comments.

@NuriAmari NuriAmari force-pushed the ns-option-linkage-conflict branch from 6a6b4f6 to 508d5d6 Compare March 8, 2023 17:01
@NuriAmari
Copy link
Contributor Author

@swift-ci Please test

@NuriAmari
Copy link
Contributor Author

@swift-ci Please test source compatibility

@NuriAmari
Copy link
Contributor Author

RAII AST meddling no more -- teach the mangler to handle it instead.

@NuriAmari
Copy link
Contributor Author

@swift-ci Please test source compatibility

CF_OPTIONS is defined differently in the SDK based on
a __cplusplus preprocessor branch. As a result, declarations
referencing CF_OPTIONS are mangled differently depending
on if C++ interop is enabled.

This meant a module compiled with cxx interop on could
not be linked with a module compiled without and vice versa.
This patch modifies the mangler such that the mangled names
are consistent. This is achieved by feeding the mangler a modified
AST node that looks like the Objective-C definition of CF_OPTIONS,
even when we have cxx interop enabled.
@NuriAmari NuriAmari force-pushed the ns-option-linkage-conflict branch from 508d5d6 to 709321b Compare March 9, 2023 17:37
@NuriAmari
Copy link
Contributor Author

@swift-ci Please test

@NuriAmari
Copy link
Contributor Author

@swift-ci Please test source compatibility

@NuriAmari
Copy link
Contributor Author

@swift-ci Please test macOS platform

@NuriAmari
Copy link
Contributor Author

@swift-ci Please Test Source Compatibility Release

@NuriAmari NuriAmari merged commit fe2f857 into main Mar 17, 2023
@NuriAmari NuriAmari deleted the ns-option-linkage-conflict branch March 17, 2023 16:33
plotfi added a commit to plotfi/swift that referenced this pull request Jun 14, 2023
… be desugared

This patch is an add-on to swiftlang#64043.
Essentially when encountering NS_OPTIONS enums, in C++-Interop mode
if they are not specially handled then they can mangle differently than
they do without C++-Interop. This patch adds logic to handle when a
typedef and enum have additional clang::ElaboratedType sugar, but
otherwise it does the same as the existing 64043 patch.

The test case provided was encountered in a real app build. The problem
came from when two modules are each compiled one with and one without
C++-Interop. For the test case code provided the mangling of the
protocol conformance is not consistent and the code in
SILGenLazyConformance.cpp crashes on an invalid conformance with reason
"Invalid conformance in type-checked AST".
plotfi added a commit to plotfi/swift that referenced this pull request Jun 15, 2023
… be desugared

This patch is an add-on to swiftlang#64043.
Essentially when encountering NS_OPTIONS enums, in C++-Interop mode
if they are not specially handled then they can mangle differently than
they do without C++-Interop. This patch adds logic to handle when a
typedef and enum have additional clang::ElaboratedType sugar, but
otherwise it does the same as the existing 64043 patch.

The test case provided was encountered in a real app build. The problem
came from when two modules are each compiled one with and one without
C++-Interop. For the test case code provided the mangling of the
protocol conformance is not consistent and the code in
SILGenLazyConformance.cpp crashes on an invalid conformance with reason
"Invalid conformance in type-checked AST".
plotfi added a commit to plotfi/swift that referenced this pull request Jun 15, 2023
… be desugared

This patch is an add-on to swiftlang#64043.
Essentially when encountering NS_OPTIONS enums, in C++-Interop mode
if they are not specially handled then they can mangle differently than
they do without C++-Interop. This patch adds logic to handle when a
typedef and enum have additional clang::ElaboratedType sugar, but
otherwise it does the same as the existing 64043 patch.

The test case provided was encountered in a real app build. The problem
came from when two modules are each compiled one with and one without
C++-Interop. For the test case code provided the mangling of the
protocol conformance is not consistent and the code in
SILGenLazyConformance.cpp crashes on an invalid conformance with reason
"Invalid conformance in type-checked AST".
plotfi added a commit to plotfi/swift that referenced this pull request Jun 16, 2023
… be desugared

This patch is an add-on to swiftlang#64043.
Essentially when encountering NS_OPTIONS enums, in C++-Interop mode
if they are not specially handled then they can mangle differently than
they do without C++-Interop. This patch adds logic to handle when a
typedef and enum have additional clang::ElaboratedType sugar, but
otherwise it does the same as the existing 64043 patch.

The test case provided was encountered in a real app build. The problem
came from when two modules are each compiled one with and one without
C++-Interop. For the test case code provided the mangling of the
protocol conformance is not consistent and the code in
SILGenLazyConformance.cpp crashes on an invalid conformance with reason
"Invalid conformance in type-checked AST".

(cherry picked from commit fe6ccd7)
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.

4 participants