Skip to content

[ClangImporter] Fix import of aliased enum cases #80557

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
Apr 7, 2025

Conversation

beccadax
Copy link
Contributor

@beccadax beccadax commented Apr 5, 2025

When a C enum has multiple constants with the same value, ClangImporter selects one of them to import as an EnumElementDecl and imports the others as VarDecl “aliases” of that one. This helps preserve the invariant that each case of an enum has a unique raw value and is distinct for exhaustiveness checking.

However, a bug in that logic could sometimes cause the canonical case to be imported twice—once as an EnumElementDecl and again as a VarDecl alias. In this situation, the EnumElementDecl was not added to the enum’s member list, resulting in a malformed AST. This bug has apparently been present since early 2017 (!), but it seems to have been harmless until recently, when the ComputeSideEffects SIL pass recently became sensitive to it (probably because of either #79872 or #80263).

Correct this problem by modifying the memoization logic to retrieve the canonical case’s clang-side constant so the subsequent check will succeed. Additionally change a variable name and add comments to help clarify this code for future maintainers.

In lieu of adding new unit tests, this commit adds a (slightly expensive) conditional assertion to catch this kind of AST malformation. There are actually about twenty tests that will fail with just the assertion and not the fix, but I’ve updated one of them to enable the assertion even in release mode.

Fixes rdar://148213237. Followup to #80487, which added related assertions to the SIL layer.

When a C enum has multiple constants with the same value, ClangImporter selects one of them to import as an `EnumElementDecl` and imports the others as `VarDecl` “aliases” of that one. This helps preserve the invariant that each case of an enum has a unique raw value and is distinct for exhaustiveness checking.

However, a bug in that logic could sometimes cause the canonical case to be imported *twice*—once as an `EnumElementDecl` and again as a `VarDecl` alias. In this situation, the `EnumElementDecl` was not added to the enum’s member list, resulting in a malformed AST. This bug has apparently been present since early 2017 (!), but it seems to have been harmless until recently, when the `ComputeSideEffects` SIL pass recently became sensitive to it (probably because of either swiftlang#79872 or swiftlang#80263).

Correct this problem by modifying the memoization logic to retrieve the canonical case’s clang-side constant so the subsequent check will succeed. Additionally change a variable name and add comments to help clarify this code for future maintainers.

In lieu of adding new unit tests, this commit adds a (slightly expensive) conditional assertion to catch this kind of AST malformation. There are actually about twenty tests that will fail with just the assertion and not the fix, but I’ve updated one of them to enable the assertion even in release mode.

Fixes rdar://148213237. Followup to swiftlang#80487, which added related assertions to the SIL layer.
@beccadax
Copy link
Contributor Author

beccadax commented Apr 5, 2025

@swift-ci please test

@beccadax
Copy link
Contributor Author

beccadax commented Apr 5, 2025

@swift-ci please test source compatibility

@beccadax
Copy link
Contributor Author

beccadax commented Apr 5, 2025

(Testing source compatibility to check this change against more surface area.)

@beccadax beccadax requested a review from nkcsgexi April 5, 2025 04:02
Copy link
Contributor

@nkcsgexi nkcsgexi left a comment

Choose a reason for hiding this comment

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

Thank you for addressing this issue so quickly, Becca!

@beccadax
Copy link
Contributor Author

beccadax commented Apr 7, 2025

@swift-ci please test Linux platform

@swift-ci please test Windows platform

@beccadax
Copy link
Contributor Author

beccadax commented Apr 7, 2025

@swift-ci please test Linux platform

@beccadax beccadax enabled auto-merge April 7, 2025 18:36
@beccadax beccadax merged commit 274c4d9 into swiftlang:main Apr 7, 2025
7 checks passed
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.

3 participants