diff options
author | bors <bors@rust-lang.org> | 2023-05-14 10:45:39 +0000 |
---|---|---|
committer | bors <bors@rust-lang.org> | 2023-05-14 10:45:39 +0000 |
commit | 3603a84a3d74d0b70dbbdaa47ed8f8a306f3fe7f (patch) | |
tree | ef0a961b9fe41ee699873b51f9298b632458578c /tests | |
parent | 0a0e045e50352d5b8c5c99e965c16aa978a0cbe1 (diff) | |
parent | 9c418e5170a2fb125ae260af1fd94e538201888d (diff) | |
download | rust-3603a84a3d74d0b70dbbdaa47ed8f8a306f3fe7f.tar.gz |
Auto merge of #111517 - lukas-code:addr-of-mutate, r=tmiasko
allow mutating function args through `&raw const`
Fixes https://github.com/rust-lang/rust/issues/111502 by "turning off the sketchy optimization while we figure out if this is ok", like `@JakobDegen` said.
The first commit in this PR removes some suspicious looking logic from the same method, but should have no functional changes, since it doesn't modify the `context` outside of the method. Best reviewed commit by commit.
r? opsem
Diffstat (limited to 'tests')
-rw-r--r-- | tests/codegen/addr-of-mutate.rs | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/tests/codegen/addr-of-mutate.rs b/tests/codegen/addr-of-mutate.rs new file mode 100644 index 00000000000..bea1aad2352 --- /dev/null +++ b/tests/codegen/addr-of-mutate.rs @@ -0,0 +1,34 @@ +// compile-flags: -C opt-level=3 -C no-prepopulate-passes +// min-llvm-version: 15.0 (for opaque pointers) + +#![crate_type = "lib"] + +// Test for the absence of `readonly` on the argument when it is mutated via `&raw const`. +// See <https://github.com/rust-lang/rust/issues/111502>. + +// CHECK: i8 @foo(ptr noalias nocapture noundef dereferenceable(128) %x) +#[no_mangle] +pub fn foo(x: [u8; 128]) -> u8 { + let ptr = core::ptr::addr_of!(x).cast_mut(); + unsafe { + (*ptr)[0] = 1; + } + x[0] +} + +// CHECK: i1 @second(ptr noalias nocapture noundef dereferenceable({{[0-9]+}}) %a_ptr_and_b) +#[no_mangle] +pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool { + let b_bool_ptr = core::ptr::addr_of!(a_ptr_and_b.1.1).cast_mut(); + (*b_bool_ptr) = true; + a_ptr_and_b.1.1 +} + +// If going through a deref (and there are no other mutating accesses), then `readonly` is fine. +// CHECK: i1 @third(ptr noalias nocapture noundef readonly dereferenceable({{[0-9]+}}) %a_ptr_and_b) +#[no_mangle] +pub unsafe fn third(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool { + let b_bool_ptr = core::ptr::addr_of!((*a_ptr_and_b.0).1).cast_mut(); + (*b_bool_ptr) = true; + a_ptr_and_b.1.1 +} |