Skip to content

Commit 3dd2f1e

Browse files
committed
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.
1 parent fd17dea commit 3dd2f1e

File tree

7 files changed

+25
-13
lines changed

7 files changed

+25
-13
lines changed

compiler/rustc_target/src/callconv/mod.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -367,13 +367,10 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
367367
let mut attrs = ArgAttributes::new();
368368

369369
// For non-immediate arguments the callee gets its own copy of
370-
// the value on the stack, so there are no aliases. It's also
371-
// program-invisible so can't possibly capture
372-
attrs
373-
.set(ArgAttribute::NoAlias)
374-
.set(ArgAttribute::NoCapture)
375-
.set(ArgAttribute::NonNull)
376-
.set(ArgAttribute::NoUndef);
370+
// the value on the stack, so there are no aliases. Note that this
371+
// pointer *is* program-visible if the function creates a pointer
372+
// to its argument!
373+
attrs.set(ArgAttribute::NoAlias).set(ArgAttribute::NonNull).set(ArgAttribute::NoUndef);
377374
attrs.pointee_size = layout.size;
378375
attrs.pointee_align = Some(layout.align.abi);
379376

tests/ui/abi/c-zst.powerpc-linux.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
2828
},
2929
mode: Indirect {
3030
attrs: ArgAttributes {
31-
regular: NoAlias | NoCapture | NonNull | NoUndef,
31+
regular: NoAlias | NonNull | NoUndef,
3232
arg_ext: None,
3333
pointee_size: Size(0 bytes),
3434
pointee_align: Some(

tests/ui/abi/c-zst.s390x-linux.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
2828
},
2929
mode: Indirect {
3030
attrs: ArgAttributes {
31-
regular: NoAlias | NoCapture | NonNull | NoUndef,
31+
regular: NoAlias | NonNull | NoUndef,
3232
arg_ext: None,
3333
pointee_size: Size(0 bytes),
3434
pointee_align: Some(

tests/ui/abi/c-zst.sparc64-linux.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
2828
},
2929
mode: Indirect {
3030
attrs: ArgAttributes {
31-
regular: NoAlias | NoCapture | NonNull | NoUndef,
31+
regular: NoAlias | NonNull | NoUndef,
3232
arg_ext: None,
3333
pointee_size: Size(0 bytes),
3434
pointee_align: Some(

tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
2828
},
2929
mode: Indirect {
3030
attrs: ArgAttributes {
31-
regular: NoAlias | NoCapture | NonNull | NoUndef,
31+
regular: NoAlias | NonNull | NoUndef,
3232
arg_ext: None,
3333
pointee_size: Size(0 bytes),
3434
pointee_align: Some(

tests/ui/abi/debug.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ error: ABIs are not compatible
465465
},
466466
mode: Indirect {
467467
attrs: ArgAttributes {
468-
regular: NoAlias | NoCapture | NonNull | NoUndef,
468+
regular: NoAlias | NonNull | NoUndef,
469469
arg_ext: None,
470470
pointee_size: Size(32 bytes),
471471
pointee_align: Some(
@@ -540,7 +540,7 @@ error: ABIs are not compatible
540540
},
541541
mode: Indirect {
542542
attrs: ArgAttributes {
543-
regular: NoAlias | NoCapture | NonNull | NoUndef,
543+
regular: NoAlias | NonNull | NoUndef,
544544
arg_ext: None,
545545
pointee_size: Size(128 bytes),
546546
pointee_align: Some(
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Regression test for issue #137668 where an indirect argument have been marked as nocapture
2+
// despite the fact that callee did in fact capture the address.
3+
//
4+
//@ run-pass
5+
//@ compile-flags: -Copt-level=2
6+
7+
#[inline(never)]
8+
pub fn f(a: [u32; 64], b: [u32; 64]) -> bool {
9+
&a as *const _ as usize != &b as *const _ as usize
10+
}
11+
12+
fn main() {
13+
static S: [u32; 64] = [0; 64];
14+
assert!(f(S, S));
15+
}

0 commit comments

Comments
 (0)