Skip to content

6.3: Fix KeyPath with 16-byte-aligned subscript traps on 32-bit targets#89323

Merged
MaxDesiatov merged 1 commit into
swiftlang:release/6.3from
MaxDesiatov:maxd/6.3-keypath-32bit
May 22, 2026
Merged

6.3: Fix KeyPath with 16-byte-aligned subscript traps on 32-bit targets#89323
MaxDesiatov merged 1 commit into
swiftlang:release/6.3from
MaxDesiatov:maxd/6.3-keypath-32bit

Conversation

@MaxDesiatov

@MaxDesiatov MaxDesiatov commented May 21, 2026

Copy link
Copy Markdown
Contributor

Cherry-pick of #88725

  • Explanation: Fixes a crash with key paths on 32-bit platforms reproducible for types that have 16-byte alignment. The intended bit layout of ComputedArgumentSize in KeyPath on 32-bit is:
 ┌───────┬───────────┐
 │ bits  │   field   │
 ├───────┼───────────┤
 │ 0–27  │ size      │
 ├───────┼───────────┤
 │ 28–29 │ padding   │
 ├───────┼───────────┤
 │ 30–31 │ alignment │
 └───────┴───────────┘

Currently, alignmentMask = 0x6000_0000, i.e. bits 29–30, not 30–31. It overlaps paddingMask (bits 28–29) at bit 29, meaning that alignment and padding unintentionally share a bit. With alignmentShift = 30, storing shift = 2 << 30 places 1 at bit 31, which the mask doesn't cover.

Correct value is 0xC000_0000 covers bits 30–31, which matches alignmentShift = 30 so both shift = 1 and shift = 2 round-trip, and it does not overlap with paddingMask = 0x3000_0000 (bits 28–29). It also mirrors the 64-bit layout (top bits of the word reserved for alignment, just 2 of them instead of 1).

  • Scope: Limited to 32-bit platforms.
  • Issues:
    rdar://175799967
    rdar://177213829
  • Risk: Very low due to increased test coverage and sufficient incubation time on main and release/6.4.
  • Testing: Previously crashing on 32-bit platforms sample code is now added to the test suite.
  • Reviewers: @Azoy @kateinoigakukun

- **Explanation**: Fixes a crash with key paths on 32-bit platforms reproducible for types that have 16-byte alignment.
The intended bit layout of `ComputedArgumentSize` in `KeyPath` on 32-bit is:
```
 ┌───────┬───────────┐
 │ bits  │   field   │
 ├───────┼───────────┤
 │ 0–27  │ size      │
 ├───────┼───────────┤
 │ 28–29 │ padding   │
 ├───────┼───────────┤
 │ 30–31 │ alignment │
 └───────┴───────────┘
```
Currently, `alignmentMask = 0x6000_0000`, i.e. bits 29–30, not 30–31. It overlaps paddingMask (bits 28–29) at bit 29, meaning that alignment and padding unintentionally share a bit. With `alignmentShift = 30`, storing `shift = 2 << 30` places 1 at bit 31, which the mask doesn't cover.

Correct value is `0xC000_0000` covers bits 30–31, which matches `alignmentShift = 30` so both `shift = 1` and `shift = 2` round-trip, and it does not overlap with `paddingMask = 0x3000_0000` (bits 28–29). It also mirrors the 64-bit layout (top bits of the word reserved for alignment, just 2 of them instead of 1).
- **Scope**: Limited to 32-bit platforms.
- **Issues**: rdar://175799967
- **Risk**: Low due to increased test coverage.
- **Testing**: Previously crashing on 32-bit platforms sample code is now added to the test suite.
@MaxDesiatov MaxDesiatov requested a review from a team as a code owner May 21, 2026 16:48
@MaxDesiatov MaxDesiatov requested a review from Azoy May 21, 2026 16:48
@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@MaxDesiatov MaxDesiatov enabled auto-merge (squash) May 21, 2026 19:33
@MaxDesiatov MaxDesiatov merged commit 6254a91 into swiftlang:release/6.3 May 22, 2026
6 checks passed
@MaxDesiatov MaxDesiatov deleted the maxd/6.3-keypath-32bit branch May 22, 2026 01:12
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