Skip to content

Commit 999774d

Browse files
committed
Auto merge of #3645 - rust-lang:rustup-2024-05-30, r=RalfJung
Automatic Rustup
2 parents 952aa4d + fa74b67 commit 999774d

13 files changed

+175
-41
lines changed

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
d86e1229411c086e1267c80dd9872959ca13b8b9
1+
caa187f3bc9604c78dfbc3ffabbe1372cb528639

src/concurrency/thread.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -861,14 +861,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
861861
if tcx.is_foreign_item(def_id) {
862862
throw_unsup_format!("foreign thread-local statics are not supported");
863863
}
864-
let allocation = this.ctfe_query(|tcx| tcx.eval_static_initializer(def_id))?;
865-
let mut allocation = allocation.inner().clone();
864+
let alloc = this.ctfe_query(|tcx| tcx.eval_static_initializer(def_id))?;
865+
// We make a full copy of this allocation.
866+
let mut alloc =
867+
alloc.inner().adjust_from_tcx(&this.tcx, |ptr| this.global_root_pointer(ptr))?;
866868
// This allocation will be deallocated when the thread dies, so it is not in read-only memory.
867-
allocation.mutability = Mutability::Mut;
869+
alloc.mutability = Mutability::Mut;
868870
// Create a fresh allocation with this content.
869-
let new_alloc = this.allocate_raw_ptr(allocation, MiriMemoryKind::Tls.into())?;
870-
this.machine.threads.set_thread_local_alloc(def_id, new_alloc);
871-
Ok(new_alloc)
871+
let ptr = this.allocate_raw_ptr(alloc, MiriMemoryKind::Tls.into())?;
872+
this.machine.threads.set_thread_local_alloc(def_id, ptr);
873+
Ok(ptr)
872874
}
873875
}
874876

src/machine.rs

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Global machine state as well as implementation of the interpreter engine
22
//! `Machine` trait.
33
4-
use std::borrow::Cow;
54
use std::cell::RefCell;
65
use std::collections::hash_map::Entry;
76
use std::fmt;
@@ -1082,40 +1081,33 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
10821081
}
10831082
}
10841083

1085-
fn adjust_allocation<'b>(
1084+
fn init_alloc_extra(
10861085
ecx: &MiriInterpCx<'tcx>,
10871086
id: AllocId,
1088-
alloc: Cow<'b, Allocation>,
1089-
kind: Option<MemoryKind>,
1090-
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>
1091-
{
1092-
let kind = kind.expect("we set our STATIC_KIND so this cannot be None");
1087+
kind: MemoryKind,
1088+
size: Size,
1089+
align: Align,
1090+
) -> InterpResult<'tcx, Self::AllocExtra> {
10931091
if ecx.machine.tracked_alloc_ids.contains(&id) {
1094-
ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(
1095-
id,
1096-
alloc.size(),
1097-
alloc.align,
1098-
kind,
1099-
));
1092+
ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(id, size, align, kind));
11001093
}
11011094

1102-
let alloc = alloc.into_owned();
11031095
let borrow_tracker = ecx
11041096
.machine
11051097
.borrow_tracker
11061098
.as_ref()
1107-
.map(|bt| bt.borrow_mut().new_allocation(id, alloc.size(), kind, &ecx.machine));
1099+
.map(|bt| bt.borrow_mut().new_allocation(id, size, kind, &ecx.machine));
11081100

1109-
let race_alloc = ecx.machine.data_race.as_ref().map(|data_race| {
1101+
let data_race = ecx.machine.data_race.as_ref().map(|data_race| {
11101102
data_race::AllocState::new_allocation(
11111103
data_race,
11121104
&ecx.machine.threads,
1113-
alloc.size(),
1105+
size,
11141106
kind,
11151107
ecx.machine.current_span(),
11161108
)
11171109
});
1118-
let buffer_alloc = ecx.machine.weak_memory.then(weak_memory::AllocState::new_allocation);
1110+
let weak_memory = ecx.machine.weak_memory.then(weak_memory::AllocState::new_allocation);
11191111

11201112
// If an allocation is leaked, we want to report a backtrace to indicate where it was
11211113
// allocated. We don't need to record a backtrace for allocations which are allowed to
@@ -1126,25 +1118,14 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
11261118
Some(ecx.generate_stacktrace())
11271119
};
11281120

1129-
let alloc: Allocation<Provenance, Self::AllocExtra, Self::Bytes> = alloc.adjust_from_tcx(
1130-
&ecx.tcx,
1131-
AllocExtra {
1132-
borrow_tracker,
1133-
data_race: race_alloc,
1134-
weak_memory: buffer_alloc,
1135-
backtrace,
1136-
},
1137-
|ptr| ecx.global_root_pointer(ptr),
1138-
)?;
1139-
11401121
if matches!(kind, MemoryKind::Machine(kind) if kind.should_save_allocation_span()) {
11411122
ecx.machine
11421123
.allocation_spans
11431124
.borrow_mut()
11441125
.insert(id, (ecx.machine.current_span(), None));
11451126
}
11461127

1147-
Ok(Cow::Owned(alloc))
1128+
Ok(AllocExtra { borrow_tracker, data_race, weak_memory, backtrace })
11481129
}
11491130

11501131
fn adjust_alloc_root_pointer(
@@ -1347,7 +1328,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
13471328
}
13481329

13491330
#[inline(always)]
1350-
fn init_frame_extra(
1331+
fn init_frame(
13511332
ecx: &mut InterpCx<'tcx, Self>,
13521333
frame: Frame<'tcx, Provenance>,
13531334
) -> InterpResult<'tcx, Frame<'tcx, Provenance, FrameExtra<'tcx>>> {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//@compile-flags: -Zmiri-disable-validation
2+
#![feature(core_intrinsics, custom_mir)]
3+
use std::intrinsics::mir::*;
4+
5+
// This disables validation and uses custom MIR hit exactly the UB in the intrinsic,
6+
// rather than getting UB from the typed load or parameter passing.
7+
8+
#[custom_mir(dialect = "runtime")]
9+
pub unsafe fn deref_meta(p: *const *const [i32]) -> usize {
10+
mir!({
11+
RET = PtrMetadata(*p); //~ ERROR: Undefined Behavior: using uninitialized data
12+
Return()
13+
})
14+
}
15+
16+
fn main() {
17+
let mut p = std::mem::MaybeUninit::<*const [i32]>::uninit();
18+
unsafe {
19+
(*p.as_mut_ptr().cast::<[usize; 2]>())[1] = 4;
20+
let _meta = deref_meta(p.as_ptr().cast());
21+
}
22+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
2+
--> $DIR/ptr_metadata_uninit_slice_data.rs:LL:CC
3+
|
4+
LL | RET = PtrMetadata(*p);
5+
| ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `deref_meta` at $DIR/ptr_metadata_uninit_slice_data.rs:LL:CC
11+
note: inside `main`
12+
--> $DIR/ptr_metadata_uninit_slice_data.rs:LL:CC
13+
|
14+
LL | let _meta = deref_meta(p.as_ptr().cast());
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16+
17+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
18+
19+
error: aborting due to 1 previous error
20+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//@compile-flags: -Zmiri-disable-validation
2+
#![feature(core_intrinsics, custom_mir)]
3+
use std::intrinsics::mir::*;
4+
5+
// This disables validation and uses custom MIR hit exactly the UB in the intrinsic,
6+
// rather than getting UB from the typed load or parameter passing.
7+
8+
#[custom_mir(dialect = "runtime")]
9+
pub unsafe fn deref_meta(p: *const *const [i32]) -> usize {
10+
mir!({
11+
RET = PtrMetadata(*p); //~ ERROR: Undefined Behavior: using uninitialized data
12+
Return()
13+
})
14+
}
15+
16+
fn main() {
17+
let mut p = std::mem::MaybeUninit::<*const [i32]>::uninit();
18+
unsafe {
19+
(*p.as_mut_ptr().cast::<[*const i32; 2]>())[0] = 4 as *const i32;
20+
let _meta = deref_meta(p.as_ptr().cast());
21+
}
22+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
warning: integer-to-pointer cast
2+
--> $DIR/ptr_metadata_uninit_slice_len.rs:LL:CC
3+
|
4+
LL | (*p.as_mut_ptr().cast::<[*const i32; 2]>())[0] = 4 as *const i32;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
6+
|
7+
= help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`,
8+
= help: which means that Miri might miss pointer bugs in this program.
9+
= help: See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation.
10+
= help: To ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead.
11+
= help: You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `with_exposed_provenance` semantics.
12+
= help: Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning.
13+
= note: BACKTRACE:
14+
= note: inside `main` at $DIR/ptr_metadata_uninit_slice_len.rs:LL:CC
15+
16+
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
17+
--> $DIR/ptr_metadata_uninit_slice_len.rs:LL:CC
18+
|
19+
LL | RET = PtrMetadata(*p);
20+
| ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
21+
|
22+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
23+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
24+
= note: BACKTRACE:
25+
= note: inside `deref_meta` at $DIR/ptr_metadata_uninit_slice_len.rs:LL:CC
26+
note: inside `main`
27+
--> $DIR/ptr_metadata_uninit_slice_len.rs:LL:CC
28+
|
29+
LL | let _meta = deref_meta(p.as_ptr().cast());
30+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31+
32+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
33+
34+
error: aborting due to 1 previous error; 1 warning emitted
35+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//@compile-flags: -Zmiri-disable-validation
2+
#![feature(core_intrinsics, custom_mir)]
3+
use std::intrinsics::mir::*;
4+
5+
// This disables validation and uses custom MIR hit exactly the UB in the intrinsic,
6+
// rather than getting UB from the typed load or parameter passing.
7+
8+
#[custom_mir(dialect = "runtime")]
9+
pub unsafe fn deref_meta(p: *const *const i32) -> () {
10+
mir!({
11+
RET = PtrMetadata(*p); //~ ERROR: Undefined Behavior: using uninitialized data
12+
Return()
13+
})
14+
}
15+
16+
fn main() {
17+
// Even though the meta is the trivially-valid `()`, this is still UB
18+
19+
let p = std::mem::MaybeUninit::<*const i32>::uninit();
20+
unsafe {
21+
let _meta = deref_meta(p.as_ptr());
22+
}
23+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
2+
--> $DIR/ptr_metadata_uninit_thin.rs:LL:CC
3+
|
4+
LL | RET = PtrMetadata(*p);
5+
| ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `deref_meta` at $DIR/ptr_metadata_uninit_thin.rs:LL:CC
11+
note: inside `main`
12+
--> $DIR/ptr_metadata_uninit_thin.rs:LL:CC
13+
|
14+
LL | let _meta = deref_meta(p.as_ptr());
15+
| ^^^^^^^^^^^^^^^^^^^^^^
16+
17+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
18+
19+
error: aborting due to 1 previous error
20+

tests/fail/reading_half_a_pointer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![allow(dead_code)]
22

33
// We use packed structs to get around alignment restrictions
4-
#[repr(packed)]
4+
#[repr(C, packed)]
55
struct Data {
66
pad: u8,
77
ptr: &'static i32,

0 commit comments

Comments
 (0)