Auto merge of #149948 - WaffleLapkin:dereferenceablen't, r=RalfJung

Stop applying `dereferenceable(n)` to return types

It looks like the semantics of `dereferenceable(n)` on return types is "dereferenceable until the end of the program", which is not sound for how we were using it. See [dereferenceable on return type](https://rust-lang.zulipchat.com/#narrow/channel/136281-t-opsem/topic/LLVM.20dereferenceable.20on.20return.20type/with/563001493) zulip thread.

cc `@rust-lang/opsem` `@nikic`
This commit is contained in:
bors 2025-12-16 09:38:19 +00:00
commit 61cc47e367
2 changed files with 13 additions and 8 deletions

View file

@ -315,13 +315,18 @@ fn arg_attrs_for_rust_scalar<'tcx>(
attrs.pointee_align =
Some(pointee.align.min(cx.tcx().sess.target.max_reliable_alignment()));
// `Box` are not necessarily dereferenceable for the entire duration of the function as
// they can be deallocated at any time. Same for non-frozen shared references (see
// <https://github.com/rust-lang/rust/pull/98017>), and for mutable references to
// potentially self-referential types (see
// <https://github.com/rust-lang/unsafe-code-guidelines/issues/381>). If LLVM had a way
// to say "dereferenceable on entry" we could use it here.
attrs.pointee_size = match kind {
// LLVM dereferenceable attribute has unclear semantics on the return type,
// they seem to be "dereferenceable until the end of the program", which is
// generally, not valid for references. See
// <https://rust-lang.zulipchat.com/#narrow/channel/136281-t-opsem/topic/LLVM.20dereferenceable.20on.20return.20type/with/563001493>
_ if is_return => Size::ZERO,
// `Box` are not necessarily dereferenceable for the entire duration of the function as
// they can be deallocated at any time. Same for non-frozen shared references (see
// <https://github.com/rust-lang/rust/pull/98017>), and for mutable references to
// potentially self-referential types (see
// <https://github.com/rust-lang/unsafe-code-guidelines/issues/381>). If LLVM had a way
// to say "dereferenceable on entry" we could use it here.
PointerKind::Box { .. }
| PointerKind::SharedRef { frozen: false }
| PointerKind::MutableRef { unpin: false } => Size::ZERO,

View file

@ -85,7 +85,7 @@ pub fn option_nonzero_int(x: Option<NonZero<u64>>) -> Option<NonZero<u64>> {
#[no_mangle]
pub fn readonly_borrow(_: &i32) {}
// CHECK: noundef align 4 dereferenceable(4) ptr @readonly_borrow_ret()
// CHECK: noundef nonnull align 4 ptr @readonly_borrow_ret()
#[no_mangle]
pub fn readonly_borrow_ret() -> &'static i32 {
loop {}
@ -116,7 +116,7 @@ pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) {}
#[no_mangle]
pub fn mutable_borrow(_: &mut i32) {}
// CHECK: noundef align 4 dereferenceable(4) ptr @mutable_borrow_ret()
// CHECK: noundef nonnull align 4 ptr @mutable_borrow_ret()
#[no_mangle]
pub fn mutable_borrow_ret() -> &'static mut i32 {
loop {}