-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make mem::replace
simpler in codegen
#111010
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1635,6 +1635,7 @@ symbols! { | |
write_bytes, | ||
write_macro, | ||
write_str, | ||
write_via_move, | ||
writeln_macro, | ||
x87_reg, | ||
xer, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance) | ||
error: Undefined Behavior: dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) | ||
--> $DIR/null_pointer_write_zst.rs:LL:CC | ||
| | ||
LL | unsafe { std::ptr::null_mut::<[u8; 0]>().write(zst_val) }; | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance) | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Almost seems like for nice error messages in Miri it'd be better not to lower this to an assignment. Currently it looks like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I guess I didn't think of it being a copy instead of a deref as meaningful here. One other thing I tried was implementing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair, I guess really this is about |
||
| | ||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior | ||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// compile-flags: -O -C no-prepopulate-passes | ||
// min-llvm-version: 15.0 (for opaque pointers) | ||
// only-x86_64 (to not worry about usize differing) | ||
// ignore-debug (the debug assertions get in the way) | ||
|
||
#![crate_type = "lib"] | ||
|
||
#[no_mangle] | ||
// CHECK-LABEL: @replace_usize( | ||
pub fn replace_usize(r: &mut usize, v: usize) -> usize { | ||
// CHECK-NOT: alloca | ||
// CHECK: %[[R:.+]] = load i64, ptr %r | ||
// CHECK: store i64 %v, ptr %r | ||
// CHECK: ret i64 %[[R]] | ||
std::mem::replace(r, v) | ||
} | ||
|
||
#[no_mangle] | ||
// CHECK-LABEL: @replace_ref_str( | ||
pub fn replace_ref_str<'a>(r: &mut &'a str, v: &'a str) -> &'a str { | ||
// CHECK-NOT: alloca | ||
// CHECK: %[[A:.+]] = load ptr | ||
// CHECK: %[[B:.+]] = load i64 | ||
// CHECK-NOT: store | ||
// CHECK-NOT: load | ||
// CHECK: store ptr | ||
// CHECK: store i64 | ||
// CHECK-NOT: load | ||
// CHECK-NOT: store | ||
// CHECK: %[[P1:.+]] = insertvalue { ptr, i64 } poison, ptr %[[A]], 0 | ||
// CHECK: %[[P2:.+]] = insertvalue { ptr, i64 } %[[P1]], i64 %[[B]], 1 | ||
// CHECK: ret { ptr, i64 } %[[P2]] | ||
std::mem::replace(r, v) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
- // MIR for `write_via_move_string` before LowerIntrinsics | ||
+ // MIR for `write_via_move_string` after LowerIntrinsics | ||
|
||
fn write_via_move_string(_1: &mut String, _2: String) -> () { | ||
debug r => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:30: +0:31 | ||
debug v => _2; // in scope 0 at $DIR/lower_intrinsics.rs:+0:46: +0:47 | ||
let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:57: +0:57 | ||
let mut _3: *mut std::string::String; // in scope 0 at $DIR/lower_intrinsics.rs:+1:47: +1:48 | ||
let mut _4: std::string::String; // in scope 0 at $DIR/lower_intrinsics.rs:+1:50: +1:51 | ||
scope 1 { | ||
} | ||
|
||
bb0: { | ||
StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+1:47: +1:48 | ||
_3 = &raw mut (*_1); // scope 1 at $DIR/lower_intrinsics.rs:+1:47: +1:48 | ||
StorageLive(_4); // scope 1 at $DIR/lower_intrinsics.rs:+1:50: +1:51 | ||
_4 = move _2; // scope 1 at $DIR/lower_intrinsics.rs:+1:50: +1:51 | ||
- _0 = write_via_move::<String>(move _3, move _4) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:52 | ||
- // mir::Constant | ||
- // + span: $DIR/lower_intrinsics.rs:129:14: 129:46 | ||
- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*mut String, String) {write_via_move::<String>}, val: Value(<ZST>) } | ||
+ (*_3) = move _4; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:52 | ||
+ goto -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:52 | ||
} | ||
|
||
bb1: { | ||
StorageDead(_4); // scope 1 at $DIR/lower_intrinsics.rs:+1:51: +1:52 | ||
StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:+1:51: +1:52 | ||
goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:1: +2:2 | ||
} | ||
|
||
bb2: { | ||
return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2 | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// MIR for `manual_replace` after PreCodegen | ||
|
||
fn manual_replace(_1: &mut u32, _2: u32) -> u32 { | ||
debug r => _1; // in scope 0 at $DIR/mem_replace.rs:+0:23: +0:24 | ||
debug v => _2; // in scope 0 at $DIR/mem_replace.rs:+0:36: +0:37 | ||
let mut _0: u32; // return place in scope 0 at $DIR/mem_replace.rs:+1:9: +1:13 | ||
scope 1 { | ||
debug temp => _0; // in scope 1 at $DIR/mem_replace.rs:+1:9: +1:13 | ||
} | ||
|
||
bb0: { | ||
_0 = (*_1); // scope 0 at $DIR/mem_replace.rs:+1:16: +1:18 | ||
(*_1) = _2; // scope 1 at $DIR/mem_replace.rs:+2:5: +2:11 | ||
return; // scope 0 at $DIR/mem_replace.rs:+4:2: +4:2 | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not important, but could you use
ManuallyDrop
instead?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I probably could, but the preexisting implementation of
write
went out of its way to useintrinsics::forget
rust/library/core/src/ptr/mod.rs
Line 1369 in 4b87ed9
even though
mem::forget
doesn'trust/library/core/src/mem/mod.rs
Lines 148 to 150 in 4b87ed9
which is probably just because it has much better codegen, but in case it actually matters I'd rather just leave it like this since it sounds like you don't feel particularly strongly about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay 👍🏻