Skip to content

Make the noundef-on-Cast size guard explicit - #160313

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
Vastargazing:abi-cast-noundef-size-guard
Aug 1, 2026
Merged

Make the noundef-on-Cast size guard explicit#160313
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
Vastargazing:abi-cast-noundef-size-guard

Conversation

@Vastargazing

@Vastargazing Vastargazing commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

ArgAbi::cast_to drops the argument's ArgAttributes. #152864 restored noundef on PassMode::Cast for the Rust ABI by re-adding it via cast_to_with_attrs when layout_is_noundef is true.

This works today because adjust_for_rust_abi constructs a Reg { Integer, size } with size == layout.size. However, this assumption isn't guarded anywhere - if this pattern gets reused where a cast is wider than the layout (like foreign ABIs using Uniform::new rounding up), padding bytes would be incorrectly marked as noundef.

This PR adds an explicit size check via a new ArgAbi::cast_to_maybe_noundef helper, which only emits NoUndef if layout_is_noundef(layout) and cast.size(cx) <= layout.size.

No functional change intended. Existing tests (like abi-noundef-cast) continue to pass.

Split out from the foreign-ABI work per the Zulip thread; foreign Reg::iN sites will reuse this helper in a follow-up PR.

r? @RalfJung

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 1, 2026
@rustbot

rustbot commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

RalfJung is not on the review rotation at the moment.
They may take a while to respond.

C: HasDataLayout,
{
let target = target.into();
let attr = if layout_is_noundef(self.layout, cx) && target.size(cx) <= self.layout.size {

@RalfJung RalfJung Aug 1, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

target.size < self.layout.size should not be possible, right? So we can use == here?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ah, sure! == is much more precise since < can't happen here anyway

switched to == and updated the doc comment accordingly

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You added a comment here and then apparently deleted it again -- so was that comment not correct?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

dang! i deleted that comment thinking i'd caught it before you saw it, but you were quicker :)

It was just wrong on my part. I took a closer look and realised I'd compared the cast's unaligned byte coverage, not CastTarget::size, which aligns up. For the {f64, f32} example I gave: pair(f64, f32) covers 12 bytes unaligned, but .size(cx) is align_to(12, 8) = 16, which equals layout.size - so that site is ==, not <. Your original point holds; target.size < layout.size doesn't actually come up here.

sorry for the noise!

Adding noundef to a PassMode::Cast is only sound when the cast target covers no
more bytes than the layout, otherwise the extra register bytes are undef padding.
In adjust_for_rust_abi this holds by construction (the cast is sized to
layout.size), so the current layout_is_noundef-only check is correct but relies
on that implicitly.

Extract the decision into ArgAbi::cast_to_maybe_noundef, which forwards NoUndef
only when layout_is_noundef(layout) && cast.size == layout.size, and switch the
aggregate-immediate site to it. No behavior change.
@Vastargazing
Vastargazing force-pushed the abi-cast-noundef-size-guard branch from b03dc44 to 6d6e8d3 Compare August 1, 2026 10:06
@RalfJung

RalfJung commented Aug 1, 2026

Copy link
Copy Markdown
Member

Looks good, thanks :)

@bors r+ rollup

@rust-bors

rust-bors Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 6d6e8d3 has been approved by RalfJung

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 1, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 1, 2026
…-guard, r=RalfJung

Make the noundef-on-Cast size guard explicit

`ArgAbi::cast_to` drops the argument's `ArgAttributes`. rust-lang#152864 restored `noundef` on `PassMode::Cast` for the Rust ABI by re-adding it via `cast_to_with_attrs` when `layout_is_noundef` is true.

This works today because `adjust_for_rust_abi` constructs a `Reg { Integer, size }` with `size == layout.size`. However, this assumption isn't guarded anywhere - if this pattern gets reused where a cast is wider than the layout (like foreign ABIs using `Uniform::new` rounding up), padding bytes would be incorrectly marked as `noundef`.

This PR adds an explicit size check via a new `ArgAbi::cast_to_maybe_noundef` helper, which only emits `NoUndef` if `layout_is_noundef(layout)` and `cast.size(cx) <= layout.size`.

No functional change intended. Existing tests (like `abi-noundef-cast`) continue to pass.

Split out from the foreign-ABI work per the Zulip thread; foreign `Reg::iN` sites will reuse this helper in a follow-up PR.

r? @RalfJung
rust-bors Bot pushed a commit that referenced this pull request Aug 1, 2026
…uwer

Rollup of 10 pull requests

Successful merges:

 - #157572 (stabilize size_of_val_raw, align_of_val_raw, Layout::for_value_raw)
 - #160012 (miri: ensure validity of references and pointers we dereference and cast)
 - #160294 (Update Enzyme to resolve one of the open bugs)
 - #159503 (allocations: document that they can be read-only)
 - #160250 (When issuing suggestions for missing trait items, label unstable items)
 - #160251 (Replace unsafe usage of `NonNull::new_unchecked` with `Box::into_non_null`)
 - #160311 (Remove final use of sealed traits from stdlib)
 - #160313 (Make the noundef-on-Cast size guard explicit)
 - #160323 (Box::leak: tell people to avoid unleaking)
 - #160328 (Move `check_track_caller` into the attribute parser)
rust-bors Bot pushed a commit that referenced this pull request Aug 1, 2026
…uwer

Rollup of 12 pull requests

Successful merges:

 - #157572 (stabilize size_of_val_raw, align_of_val_raw, Layout::for_value_raw)
 - #160012 (miri: ensure validity of references and pointers we dereference and cast)
 - #160294 (Update Enzyme to resolve one of the open bugs)
 - #159503 (allocations: document that they can be read-only)
 - #160179 (std: Update `wasip3` crate dependency)
 - #160250 (When issuing suggestions for missing trait items, label unstable items)
 - #160251 (Replace unsafe usage of `NonNull::new_unchecked` with `Box::into_non_null`)
 - #160311 (Remove final use of sealed traits from stdlib)
 - #160313 (Make the noundef-on-Cast size guard explicit)
 - #160323 (Box::leak: tell people to avoid unleaking)
 - #160328 (Move `check_track_caller` into the attribute parser)
 - #160333 (Remove itertools dependency from `rustc_ast_pretty`)
@rust-bors
rust-bors Bot merged commit 2c109f1 into rust-lang:main Aug 1, 2026
13 checks passed
@rustbot rustbot added this to the 1.99.0 milestone Aug 1, 2026
rust-timer added a commit that referenced this pull request Aug 1, 2026
Rollup merge of #160313 - Vastargazing:abi-cast-noundef-size-guard, r=RalfJung

Make the noundef-on-Cast size guard explicit

`ArgAbi::cast_to` drops the argument's `ArgAttributes`. #152864 restored `noundef` on `PassMode::Cast` for the Rust ABI by re-adding it via `cast_to_with_attrs` when `layout_is_noundef` is true.

This works today because `adjust_for_rust_abi` constructs a `Reg { Integer, size }` with `size == layout.size`. However, this assumption isn't guarded anywhere - if this pattern gets reused where a cast is wider than the layout (like foreign ABIs using `Uniform::new` rounding up), padding bytes would be incorrectly marked as `noundef`.

This PR adds an explicit size check via a new `ArgAbi::cast_to_maybe_noundef` helper, which only emits `NoUndef` if `layout_is_noundef(layout)` and `cast.size(cx) <= layout.size`.

No functional change intended. Existing tests (like `abi-noundef-cast`) continue to pass.

Split out from the foreign-ABI work per the Zulip thread; foreign `Reg::iN` sites will reuse this helper in a follow-up PR.

r? @RalfJung
@Vastargazing
Vastargazing deleted the abi-cast-noundef-size-guard branch August 2, 2026 04:42
pull Bot pushed a commit to xtqqczze/rust-lang-miri that referenced this pull request Aug 2, 2026
…uwer

Rollup of 12 pull requests

Successful merges:

 - rust-lang/rust#157572 (stabilize size_of_val_raw, align_of_val_raw, Layout::for_value_raw)
 - rust-lang/rust#160012 (miri: ensure validity of references and pointers we dereference and cast)
 - rust-lang/rust#160294 (Update Enzyme to resolve one of the open bugs)
 - rust-lang/rust#159503 (allocations: document that they can be read-only)
 - rust-lang/rust#160179 (std: Update `wasip3` crate dependency)
 - rust-lang/rust#160250 (When issuing suggestions for missing trait items, label unstable items)
 - rust-lang/rust#160251 (Replace unsafe usage of `NonNull::new_unchecked` with `Box::into_non_null`)
 - rust-lang/rust#160311 (Remove final use of sealed traits from stdlib)
 - rust-lang/rust#160313 (Make the noundef-on-Cast size guard explicit)
 - rust-lang/rust#160323 (Box::leak: tell people to avoid unleaking)
 - rust-lang/rust#160328 (Move `check_track_caller` into the attribute parser)
 - rust-lang/rust#160333 (Remove itertools dependency from `rustc_ast_pretty`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants