Skip to content

🌸 [ClangImporter] Fix import of aliased enum cases #80780

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

Open
wants to merge 1 commit into
base: release/6.2
Choose a base branch
from

Conversation

beccadax
Copy link
Contributor

@beccadax beccadax commented Apr 12, 2025

  • Explanation: Corrects a bug that could cause a C enum case with aliases to be imported incorrectly, resulting in a subtly malformed AST that could sometimes crash SILOptimizer's ComputeSideEffects pass.
  • Issue: rdar://148213237
  • Risk: Low. In theory this could cause switch statement exhaustivity to (correctly) diagnose a new error, but because C enums are usually non-frozen and are rarely switched over, we didn't see any failures in compatibility tests.
  • Testing: Added assertions which are exercised by many existing tests.
  • Original PR: [ClangImporter] Fix import of aliased enum cases #80557
  • Reviewers: @Xazax-hun, @nkcsgexi

Cherry-pick of #80557:

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 beccadax requested a review from a team as a code owner April 12, 2025 00:00
@beccadax beccadax added 🍒 release cherry pick Flag: Release branch cherry picks swift 6.2 labels Apr 12, 2025
@beccadax
Copy link
Contributor Author

@swift-ci please test

@beccadax beccadax enabled auto-merge April 12, 2025 00:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🍒 release cherry pick Flag: Release branch cherry picks swift 6.2
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants