Make the noundef-on-Cast size guard explicit - #160313
Conversation
|
|
| C: HasDataLayout, | ||
| { | ||
| let target = target.into(); | ||
| let attr = if layout_is_noundef(self.layout, cx) && target.size(cx) <= self.layout.size { |
There was a problem hiding this comment.
target.size < self.layout.size should not be possible, right? So we can use == here?
There was a problem hiding this comment.
ah, sure! == is much more precise since < can't happen here anyway
switched to == and updated the doc comment accordingly
There was a problem hiding this comment.
You added a comment here and then apparently deleted it again -- so was that comment not correct?
There was a problem hiding this comment.
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.
b03dc44 to
6d6e8d3
Compare
|
Looks good, thanks :) @bors r+ rollup |
…-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
…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)
…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`)
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
…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`)
ArgAbi::cast_todrops the argument'sArgAttributes. #152864 restorednoundefonPassMode::Castfor the Rust ABI by re-adding it viacast_to_with_attrswhenlayout_is_noundefis true.This works today because
adjust_for_rust_abiconstructs aReg { Integer, size }withsize == 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 usingUniform::newrounding up), padding bytes would be incorrectly marked asnoundef.This PR adds an explicit size check via a new
ArgAbi::cast_to_maybe_noundefhelper, which only emitsNoUndefiflayout_is_noundef(layout)andcast.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::iNsites will reuse this helper in a follow-up PR.r? @RalfJung