diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 198d08864bec3..928ed90073532 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -367,13 +367,10 @@ 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. Note that this + // pointer *is* program-visible if the function creates a pointer + // to its argument! + 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/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)); +}