From 43b0a27e9618807b3f079e704c413f66de56e8a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 27 Feb 2025 13:53:07 +0100 Subject: [PATCH] Remove incorrect use of nocapture attribute When using an indirect pass mode, a callee can obtain an address of an argument and capture it. The nocapture attribute promises this does not happen and so cannot be used unconditionally. --- compiler/rustc_target/src/callconv/mod.rs | 9 ++------- .../codegen/uninhabited-transparent-return-abi.rs | 4 ++-- tests/ui/abi/c-zst.powerpc-linux.stderr | 2 +- tests/ui/abi/c-zst.s390x-linux.stderr | 2 +- tests/ui/abi/c-zst.sparc64-linux.stderr | 2 +- tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr | 2 +- tests/ui/abi/debug.stderr | 4 ++-- tests/ui/codegen/indirect-nocapture.rs | 15 +++++++++++++++ 8 files changed, 25 insertions(+), 15 deletions(-) create mode 100644 tests/ui/codegen/indirect-nocapture.rs diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 1c044fe98b3ef..7c867c646105d 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -367,13 +367,8 @@ impl<'a, Ty> ArgAbi<'a, Ty> { let mut attrs = ArgAttributes::new(); // For non-immediate arguments the callee gets its own copy of - // the value on the stack, so there are no aliases. It's also - // program-invisible so can't possibly capture - attrs - .set(ArgAttribute::NoAlias) - .set(ArgAttribute::NoCapture) - .set(ArgAttribute::NonNull) - .set(ArgAttribute::NoUndef); + // the value on the stack, so there are no aliases. + attrs.set(ArgAttribute::NoAlias).set(ArgAttribute::NonNull).set(ArgAttribute::NoUndef); attrs.pointee_size = layout.size; attrs.pointee_align = Some(layout.align.abi); diff --git a/tests/codegen/uninhabited-transparent-return-abi.rs b/tests/codegen/uninhabited-transparent-return-abi.rs index 6e8b1683163ef..ad7b6fb122a7a 100644 --- a/tests/codegen/uninhabited-transparent-return-abi.rs +++ b/tests/codegen/uninhabited-transparent-return-abi.rs @@ -24,7 +24,7 @@ extern "Rust" { pub fn test_uninhabited_ret_by_ref() { // CHECK: %_1 = alloca [24 x i8], align {{8|4}} // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_1) - // CHECK-NEXT: call void @opaque(ptr noalias nocapture noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_1) #2 + // CHECK-NEXT: call void @opaque(ptr noalias noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_1) #2 // CHECK-NEXT: unreachable unsafe { opaque(); @@ -36,7 +36,7 @@ pub fn test_uninhabited_ret_by_ref() { pub fn test_uninhabited_ret_by_ref_with_arg(rsi: u32) { // CHECK: %_2 = alloca [24 x i8], align {{8|4}} // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_2) - // CHECK-NEXT: call void @opaque_with_arg(ptr noalias nocapture noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_2, i32 noundef %rsi) #2 + // CHECK-NEXT: call void @opaque_with_arg(ptr noalias noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_2, i32 noundef %rsi) #2 // CHECK-NEXT: unreachable unsafe { opaque_with_arg(rsi); diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr index 6738017673003..08c677afb12db 100644 --- a/tests/ui/abi/c-zst.powerpc-linux.stderr +++ b/tests/ui/abi/c-zst.powerpc-linux.stderr @@ -28,7 +28,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, mode: Indirect { attrs: ArgAttributes { - regular: NoAlias | NoCapture | NonNull | NoUndef, + regular: NoAlias | NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some( diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr index 6738017673003..08c677afb12db 100644 --- a/tests/ui/abi/c-zst.s390x-linux.stderr +++ b/tests/ui/abi/c-zst.s390x-linux.stderr @@ -28,7 +28,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, mode: Indirect { attrs: ArgAttributes { - regular: NoAlias | NoCapture | NonNull | NoUndef, + regular: NoAlias | NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some( diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr index 6738017673003..08c677afb12db 100644 --- a/tests/ui/abi/c-zst.sparc64-linux.stderr +++ b/tests/ui/abi/c-zst.sparc64-linux.stderr @@ -28,7 +28,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, mode: Indirect { attrs: ArgAttributes { - regular: NoAlias | NoCapture | NonNull | NoUndef, + regular: NoAlias | NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some( diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr index 6738017673003..08c677afb12db 100644 --- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr +++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr @@ -28,7 +28,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, mode: Indirect { attrs: ArgAttributes { - regular: NoAlias | NoCapture | NonNull | NoUndef, + regular: NoAlias | NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some( diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr index 5f73ff7d6bd58..a9162177c5270 100644 --- a/tests/ui/abi/debug.stderr +++ b/tests/ui/abi/debug.stderr @@ -465,7 +465,7 @@ error: ABIs are not compatible }, mode: Indirect { attrs: ArgAttributes { - regular: NoAlias | NoCapture | NonNull | NoUndef, + regular: NoAlias | NonNull | NoUndef, arg_ext: None, pointee_size: Size(32 bytes), pointee_align: Some( @@ -540,7 +540,7 @@ error: ABIs are not compatible }, mode: Indirect { attrs: ArgAttributes { - regular: NoAlias | NoCapture | NonNull | NoUndef, + regular: NoAlias | NonNull | NoUndef, arg_ext: None, pointee_size: Size(128 bytes), pointee_align: Some( diff --git a/tests/ui/codegen/indirect-nocapture.rs b/tests/ui/codegen/indirect-nocapture.rs new file mode 100644 index 0000000000000..78024a94c0de3 --- /dev/null +++ b/tests/ui/codegen/indirect-nocapture.rs @@ -0,0 +1,15 @@ +// Regression test for issue #137668 where an indirect argument have been marked as nocapture +// despite the fact that callee did in fact capture the address. +// +//@ run-pass +//@ compile-flags: -Copt-level=2 + +#[inline(never)] +pub fn f(a: [u32; 64], b: [u32; 64]) -> bool { + &a as *const _ as usize != &b as *const _ as usize +} + +fn main() { + static S: [u32; 64] = [0; 64]; + assert!(f(S, S)); +}