Skip to content

Commit 4210835

Browse files
committed
Auto merge of #125691 - jieyouxu:rollup-0i3wrc4, r=jieyouxu
Rollup of 8 pull requests Successful merges: - #124251 (Add an intrinsic for `ptr::metadata`) - #124320 (Add `--print=check-cfg` to get the expected configs) - #125226 (Make more of the test suite run on Mac Catalyst) - #125381 (Silence some resolve errors when there have been glob import errors) - #125633 (miri: avoid making a full copy of all new allocations) - #125638 (Rewrite `lto-smoke`, `simple-rlib` and `mixing-deps` `run-make` tests in `rmake.rs` format) - #125639 (Support `./x doc run-make-support --open`) - #125664 (Tweak relations to no longer rely on `TypeTrace`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 59bbd30 + 9fc3c4e commit 4210835

9 files changed

+168
-38
lines changed

src/concurrency/thread.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -862,14 +862,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
862862
if tcx.is_foreign_item(def_id) {
863863
throw_unsup_format!("foreign thread-local statics are not supported");
864864
}
865-
let allocation = this.ctfe_query(|tcx| tcx.eval_static_initializer(def_id))?;
866-
let mut allocation = allocation.inner().clone();
865+
let alloc = this.ctfe_query(|tcx| tcx.eval_static_initializer(def_id))?;
866+
// We make a full copy of this allocation.
867+
let mut alloc = alloc.inner().adjust_from_tcx(&this.tcx, |ptr| this.global_root_pointer(ptr))?;
867868
// This allocation will be deallocated when the thread dies, so it is not in read-only memory.
868-
allocation.mutability = Mutability::Mut;
869+
alloc.mutability = Mutability::Mut;
869870
// Create a fresh allocation with this content.
870-
let new_alloc = this.allocate_raw_ptr(allocation, MiriMemoryKind::Tls.into())?;
871-
this.machine.threads.set_thread_local_alloc(def_id, new_alloc);
872-
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)
873874
}
874875
}
875876

src/machine.rs

+12-31
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;
@@ -1086,40 +1085,33 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
10861085
}
10871086
}
10881087

1089-
fn adjust_allocation<'b>(
1088+
fn init_alloc_extra(
10901089
ecx: &MiriInterpCx<'tcx>,
10911090
id: AllocId,
1092-
alloc: Cow<'b, Allocation>,
1093-
kind: Option<MemoryKind>,
1094-
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>
1095-
{
1096-
let kind = kind.expect("we set our STATIC_KIND so this cannot be None");
1091+
kind: MemoryKind,
1092+
size: Size,
1093+
align: Align,
1094+
) -> InterpResult<'tcx, Self::AllocExtra> {
10971095
if ecx.machine.tracked_alloc_ids.contains(&id) {
1098-
ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(
1099-
id,
1100-
alloc.size(),
1101-
alloc.align,
1102-
kind,
1103-
));
1096+
ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(id, size, align, kind));
11041097
}
11051098

1106-
let alloc = alloc.into_owned();
11071099
let borrow_tracker = ecx
11081100
.machine
11091101
.borrow_tracker
11101102
.as_ref()
1111-
.map(|bt| bt.borrow_mut().new_allocation(id, alloc.size(), kind, &ecx.machine));
1103+
.map(|bt| bt.borrow_mut().new_allocation(id, size, kind, &ecx.machine));
11121104

1113-
let race_alloc = ecx.machine.data_race.as_ref().map(|data_race| {
1105+
let data_race = ecx.machine.data_race.as_ref().map(|data_race| {
11141106
data_race::AllocState::new_allocation(
11151107
data_race,
11161108
&ecx.machine.threads,
1117-
alloc.size(),
1109+
size,
11181110
kind,
11191111
ecx.machine.current_span(),
11201112
)
11211113
});
1122-
let buffer_alloc = ecx.machine.weak_memory.then(weak_memory::AllocState::new_allocation);
1114+
let weak_memory = ecx.machine.weak_memory.then(weak_memory::AllocState::new_allocation);
11231115

11241116
// If an allocation is leaked, we want to report a backtrace to indicate where it was
11251117
// allocated. We don't need to record a backtrace for allocations which are allowed to
@@ -1130,25 +1122,14 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
11301122
Some(ecx.generate_stacktrace())
11311123
};
11321124

1133-
let alloc: Allocation<Provenance, Self::AllocExtra, Self::Bytes> = alloc.adjust_from_tcx(
1134-
&ecx.tcx,
1135-
AllocExtra {
1136-
borrow_tracker,
1137-
data_race: race_alloc,
1138-
weak_memory: buffer_alloc,
1139-
backtrace,
1140-
},
1141-
|ptr| ecx.global_root_pointer(ptr),
1142-
)?;
1143-
11441125
if matches!(kind, MemoryKind::Machine(kind) if kind.should_save_allocation_span()) {
11451126
ecx.machine
11461127
.allocation_spans
11471128
.borrow_mut()
11481129
.insert(id, (ecx.machine.current_span(), None));
11491130
}
11501131

1151-
Ok(Cow::Owned(alloc))
1132+
Ok(AllocExtra { borrow_tracker, data_race, weak_memory, backtrace })
11521133
}
11531134

11541135
fn adjust_alloc_root_pointer(
@@ -1357,7 +1338,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
13571338
}
13581339

13591340
#[inline(always)]
1360-
fn init_frame_extra(
1341+
fn init_frame(
13611342
ecx: &mut InterpCx<'tcx, Self>,
13621343
frame: Frame<'tcx, Provenance>,
13631344
) -> InterpResult<'tcx, Frame<'tcx, Provenance, FrameExtra<'tcx>>> {
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+
}
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+
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+
}
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+
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+
}
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/pass/intrinsics/intrinsics.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//@compile-flags: -Zmiri-permissive-provenance
2-
#![feature(core_intrinsics, layout_for_ptr)]
2+
#![feature(core_intrinsics, layout_for_ptr, ptr_metadata)]
33
//! Tests for various intrinsics that do not fit anywhere else.
44
55
use std::intrinsics;
@@ -57,4 +57,10 @@ fn main() {
5757
// Make sure that even if the discriminant is stored together with data, the intrinsic returns
5858
// only the discriminant, nothing about the data.
5959
assert_eq!(discriminant(&Some(false)), discriminant(&Some(true)));
60+
61+
let () = intrinsics::ptr_metadata(&[1, 2, 3]);
62+
let len = intrinsics::ptr_metadata(&[1, 2, 3][..]);
63+
assert_eq!(len, 3);
64+
let dyn_meta = intrinsics::ptr_metadata(&[1, 2, 3] as &dyn std::fmt::Debug);
65+
assert_eq!(dyn_meta.size_of(), 12);
6066
}

0 commit comments

Comments
 (0)