Skip to content

Commit c104861

Browse files
committed
Auto merge of #116940 - matthiaskrgr:rollup-25ezp8a, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #116650 (add some comments and some cleanup around Miri intptrcast) - #116896 (Only check in a single place if a pass is enabled.) - #116906 (Use v0.0.0 in compiler crates) - #116921 (fix(bootstrap) info message show correct path now) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3fbcfd2 + e8544f8 commit c104861

File tree

13 files changed

+110
-49
lines changed

13 files changed

+110
-49
lines changed

Cargo.lock

+5-5
Original file line numberDiff line numberDiff line change
@@ -3839,7 +3839,7 @@ dependencies = [
38393839

38403840
[[package]]
38413841
name = "rustc_fluent_macro"
3842-
version = "0.1.0"
3842+
version = "0.0.0"
38433843
dependencies = [
38443844
"annotate-snippets",
38453845
"fluent-bundle",
@@ -3915,7 +3915,7 @@ dependencies = [
39153915

39163916
[[package]]
39173917
name = "rustc_hir_typeck"
3918-
version = "0.1.0"
3918+
version = "0.0.0"
39193919
dependencies = [
39203920
"rustc_ast",
39213921
"rustc_attr",
@@ -4043,7 +4043,7 @@ dependencies = [
40434043

40444044
[[package]]
40454045
name = "rustc_lexer"
4046-
version = "0.1.0"
4046+
version = "0.0.0"
40474047
dependencies = [
40484048
"expect-test",
40494049
"unicode-properties",
@@ -4112,7 +4112,7 @@ dependencies = [
41124112

41134113
[[package]]
41144114
name = "rustc_macros"
4115-
version = "0.1.0"
4115+
version = "0.0.0"
41164116
dependencies = [
41174117
"proc-macro2",
41184118
"quote",
@@ -4595,7 +4595,7 @@ dependencies = [
45954595

45964596
[[package]]
45974597
name = "rustc_transmute"
4598-
version = "0.1.0"
4598+
version = "0.0.0"
45994599
dependencies = [
46004600
"itertools",
46014601
"rustc_data_structures",

compiler/rustc_const_eval/src/interpret/memory.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
12351235

12361236
/// Turning a "maybe pointer" into a proper pointer (and some information
12371237
/// about where it points), or an absolute address.
1238+
///
1239+
/// The result must be used immediately; it is not allowed to convert
1240+
/// the returned data back into a `Pointer` and store that in machine state.
1241+
/// (In fact that's not even possible since `M::ProvenanceExtra` is generic and
1242+
/// we don't have an operation to turn it back into `M::Provenance`.)
12381243
pub fn ptr_try_get_alloc_id(
12391244
&self,
12401245
ptr: Pointer<Option<M::Provenance>>,
@@ -1253,6 +1258,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
12531258
}
12541259

12551260
/// Turning a "maybe pointer" into a proper pointer (and some information about where it points).
1261+
///
1262+
/// The result must be used immediately; it is not allowed to convert
1263+
/// the returned data back into a `Pointer` and store that in machine state.
1264+
/// (In fact that's not even possible since `M::ProvenanceExtra` is generic and
1265+
/// we don't have an operation to turn it back into `M::Provenance`.)
12561266
#[inline(always)]
12571267
pub fn ptr_get_alloc_id(
12581268
&self,

compiler/rustc_fluent_macro/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rustc_fluent_macro"
3-
version = "0.1.0"
3+
version = "0.0.0"
44
edition = "2021"
55

66
[lib]

compiler/rustc_hir_typeck/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rustc_hir_typeck"
3-
version = "0.1.0"
3+
version = "0.0.0"
44
edition = "2021"
55

66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

compiler/rustc_lexer/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rustc_lexer"
3-
version = "0.1.0"
3+
version = "0.0.0"
44
license = "MIT OR Apache-2.0"
55
edition = "2021"
66

compiler/rustc_macros/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rustc_macros"
3-
version = "0.1.0"
3+
version = "0.0.0"
44
edition = "2021"
55

66
[lib]

compiler/rustc_mir_transform/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
383383
let is_fn_like = tcx.def_kind(def).is_fn_like();
384384
if is_fn_like {
385385
// Do not compute the mir call graph without said call graph actually being used.
386-
if inline::Inline.is_enabled(&tcx.sess) {
386+
if pm::should_run_pass(tcx, &inline::Inline) {
387387
tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def.to_def_id()));
388388
}
389389
}

compiler/rustc_mir_transform/src/pass_manager.rs

+21-12
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,25 @@ pub fn run_passes<'tcx>(
8383
run_passes_inner(tcx, body, passes, phase_change, true);
8484
}
8585

86+
pub fn should_run_pass<'tcx, P>(tcx: TyCtxt<'tcx>, pass: &P) -> bool
87+
where
88+
P: MirPass<'tcx> + ?Sized,
89+
{
90+
let name = pass.name();
91+
92+
let overridden_passes = &tcx.sess.opts.unstable_opts.mir_enable_passes;
93+
let overridden =
94+
overridden_passes.iter().rev().find(|(s, _)| s == &*name).map(|(_name, polarity)| {
95+
trace!(
96+
pass = %name,
97+
"{} as requested by flag",
98+
if *polarity { "Running" } else { "Not running" },
99+
);
100+
*polarity
101+
});
102+
overridden.unwrap_or_else(|| pass.is_enabled(&tcx.sess))
103+
}
104+
86105
fn run_passes_inner<'tcx>(
87106
tcx: TyCtxt<'tcx>,
88107
body: &mut Body<'tcx>,
@@ -100,19 +119,9 @@ fn run_passes_inner<'tcx>(
100119
for pass in passes {
101120
let name = pass.name();
102121

103-
let overridden = overridden_passes.iter().rev().find(|(s, _)| s == &*name).map(
104-
|(_name, polarity)| {
105-
trace!(
106-
pass = %name,
107-
"{} as requested by flag",
108-
if *polarity { "Running" } else { "Not running" },
109-
);
110-
*polarity
111-
},
112-
);
113-
if !overridden.unwrap_or_else(|| pass.is_enabled(&tcx.sess)) {
122+
if !should_run_pass(tcx, *pass) {
114123
continue;
115-
}
124+
};
116125

117126
let dump_enabled = pass.is_mir_dump_enabled();
118127

compiler/rustc_transmute/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rustc_transmute"
3-
version = "0.1.0"
3+
version = "0.0.0"
44
edition = "2021"
55

66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

src/bootstrap/src/core/build_steps/setup.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ pub fn setup(config: &Config, profile: Profile) {
183183
eprintln!();
184184
eprintln!(
185185
"note: the `tools` profile sets up the `stage2` toolchain (use \
186-
`rustup toolchain link 'name' host/build/stage2` to use rustc)"
186+
`rustup toolchain link 'name' build/host/stage2` to use rustc)"
187187
)
188188
}
189189

src/tools/miri/src/intptrcast.rs

+18-19
Original file line numberDiff line numberDiff line change
@@ -119,24 +119,14 @@ impl<'mir, 'tcx> GlobalStateInner {
119119
Ok(())
120120
}
121121

122-
pub fn ptr_from_addr_transmute(
123-
_ecx: &MiriInterpCx<'mir, 'tcx>,
124-
addr: u64,
125-
) -> Pointer<Option<Provenance>> {
126-
trace!("Transmuting {:#x} to a pointer", addr);
127-
128-
// We consider transmuted pointers to be "invalid" (`None` provenance).
129-
Pointer::new(None, Size::from_bytes(addr))
130-
}
131-
132122
pub fn ptr_from_addr_cast(
133123
ecx: &MiriInterpCx<'mir, 'tcx>,
134124
addr: u64,
135125
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
136126
trace!("Casting {:#x} to a pointer", addr);
137127

128+
// Potentially emit a warning.
138129
let global_state = ecx.machine.intptrcast.borrow();
139-
140130
match global_state.provenance_mode {
141131
ProvenanceMode::Default => {
142132
// The first time this happens at a particular location, print a warning.
@@ -158,7 +148,12 @@ impl<'mir, 'tcx> GlobalStateInner {
158148
ProvenanceMode::Permissive => {}
159149
}
160150

161-
// This is how wildcard pointers are born.
151+
// We do *not* look up the `AllocId` here! This is a `ptr as usize` cast, and it is
152+
// completely legal to do a cast and then `wrapping_offset` to another allocation and only
153+
// *then* do a memory access. So the allocation that the pointer happens to point to on a
154+
// cast is fairly irrelevant. Instead we generate this as a "wildcard" pointer, such that
155+
// *every time the pointer is used*, we do an `AllocId` lookup to find the (exposed)
156+
// allocation it might be referencing.
162157
Ok(Pointer::new(Some(Provenance::Wildcard), Size::from_bytes(addr)))
163158
}
164159

@@ -219,22 +214,27 @@ impl<'mir, 'tcx> GlobalStateInner {
219214
})
220215
}
221216

222-
/// Convert a relative (tcx) pointer to an absolute address.
223-
pub fn rel_ptr_to_addr(
217+
/// Convert a relative (tcx) pointer to a Miri pointer.
218+
pub fn ptr_from_rel_ptr(
224219
ecx: &MiriInterpCx<'mir, 'tcx>,
225220
ptr: Pointer<AllocId>,
226-
) -> InterpResult<'tcx, u64> {
221+
tag: BorTag,
222+
) -> InterpResult<'tcx, Pointer<Provenance>> {
227223
let (alloc_id, offset) = ptr.into_parts(); // offset is relative (AllocId provenance)
228224
let base_addr = GlobalStateInner::alloc_base_addr(ecx, alloc_id)?;
229225

230226
// Add offset with the right kind of pointer-overflowing arithmetic.
231227
let dl = ecx.data_layout();
232-
Ok(dl.overflowing_offset(base_addr, offset.bytes()).0)
228+
let absolute_addr = dl.overflowing_offset(base_addr, offset.bytes()).0;
229+
Ok(Pointer::new(
230+
Provenance::Concrete { alloc_id, tag },
231+
Size::from_bytes(absolute_addr),
232+
))
233233
}
234234

235235
/// When a pointer is used for a memory access, this computes where in which allocation the
236236
/// access is going.
237-
pub fn abs_ptr_to_rel(
237+
pub fn ptr_get_alloc(
238238
ecx: &MiriInterpCx<'mir, 'tcx>,
239239
ptr: Pointer<Provenance>,
240240
) -> Option<(AllocId, Size)> {
@@ -252,12 +252,11 @@ impl<'mir, 'tcx> GlobalStateInner {
252252
let base_addr = GlobalStateInner::alloc_base_addr(ecx, alloc_id).unwrap();
253253

254254
// Wrapping "addr - base_addr"
255-
let dl = ecx.data_layout();
256255
#[allow(clippy::cast_possible_wrap)] // we want to wrap here
257256
let neg_base_addr = (base_addr as i64).wrapping_neg();
258257
Some((
259258
alloc_id,
260-
Size::from_bytes(dl.overflowing_signed_offset(addr.bytes(), neg_base_addr).0),
259+
Size::from_bytes(ecx.overflowing_signed_offset(addr.bytes(), neg_base_addr).0),
261260
))
262261
}
263262

src/tools/miri/src/machine.rs

+30-6
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,29 @@ impl fmt::Display for MiriMemoryKind {
168168
/// Pointer provenance.
169169
#[derive(Clone, Copy)]
170170
pub enum Provenance {
171+
/// For pointers with concrete provenance. we exactly know which allocation they are attached to
172+
/// and what their borrow tag is.
171173
Concrete {
172174
alloc_id: AllocId,
173175
/// Borrow Tracker tag.
174176
tag: BorTag,
175177
},
178+
/// Pointers with wildcard provenance are created on int-to-ptr casts. According to the
179+
/// specification, we should at that point angelically "guess" a provenance that will make all
180+
/// future uses of this pointer work, if at all possible. Of course such a semantics cannot be
181+
/// actually implemented in Miri. So instead, we approximate this, erroring on the side of
182+
/// accepting too much code rather than rejecting correct code: a pointer with wildcard
183+
/// provenance "acts like" any previously exposed pointer. Each time it is used, we check
184+
/// whether *some* exposed pointer could have done what we want to do, and if the answer is yes
185+
/// then we allow the access. This allows too much code in two ways:
186+
/// - The same wildcard pointer can "take the role" of multiple different exposed pointers on
187+
/// subsequenct memory accesses.
188+
/// - In the aliasing model, we don't just have to know the borrow tag of the pointer used for
189+
/// the access, we also have to update the aliasing state -- and that update can be very
190+
/// different depending on which borrow tag we pick! Stacked Borrows has support for this by
191+
/// switching to a stack that is only approximately known, i.e. we overapproximate the effect
192+
/// of using *any* exposed pointer for this access, and only keep information about the borrow
193+
/// stack that would be true with all possible choices.
176194
Wildcard,
177195
}
178196

@@ -1122,19 +1140,16 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
11221140
_ => {}
11231141
}
11241142
}
1125-
let absolute_addr = intptrcast::GlobalStateInner::rel_ptr_to_addr(ecx, ptr)?;
11261143
let tag = if let Some(borrow_tracker) = &ecx.machine.borrow_tracker {
11271144
borrow_tracker.borrow_mut().base_ptr_tag(ptr.provenance, &ecx.machine)
11281145
} else {
11291146
// Value does not matter, SB is disabled
11301147
BorTag::default()
11311148
};
1132-
Ok(Pointer::new(
1133-
Provenance::Concrete { alloc_id: ptr.provenance, tag },
1134-
Size::from_bytes(absolute_addr),
1135-
))
1149+
intptrcast::GlobalStateInner::ptr_from_rel_ptr(ecx, ptr, tag)
11361150
}
11371151

1152+
/// Called on `usize as ptr` casts.
11381153
#[inline(always)]
11391154
fn ptr_from_addr_cast(
11401155
ecx: &MiriInterpCx<'mir, 'tcx>,
@@ -1143,6 +1158,9 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
11431158
intptrcast::GlobalStateInner::ptr_from_addr_cast(ecx, addr)
11441159
}
11451160

1161+
/// Called on `ptr as usize` casts.
1162+
/// (Actually computing the resulting `usize` doesn't need machine help,
1163+
/// that's just `Scalar::try_to_int`.)
11461164
fn expose_ptr(
11471165
ecx: &mut InterpCx<'mir, 'tcx, Self>,
11481166
ptr: Pointer<Self::Provenance>,
@@ -1160,11 +1178,17 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
11601178

11611179
/// Convert a pointer with provenance into an allocation-offset pair,
11621180
/// or a `None` with an absolute address if that conversion is not possible.
1181+
///
1182+
/// This is called when a pointer is about to be used for memory access,
1183+
/// an in-bounds check, or anything else that requires knowing which allocation it points to.
1184+
/// The resulting `AllocId` will just be used for that one step and the forgotten again
1185+
/// (i.e., we'll never turn the data returned here back into a `Pointer` that might be
1186+
/// stored in machine state).
11631187
fn ptr_get_alloc(
11641188
ecx: &MiriInterpCx<'mir, 'tcx>,
11651189
ptr: Pointer<Self::Provenance>,
11661190
) -> Option<(AllocId, Size, Self::ProvenanceExtra)> {
1167-
let rel = intptrcast::GlobalStateInner::abs_ptr_to_rel(ecx, ptr);
1191+
let rel = intptrcast::GlobalStateInner::ptr_get_alloc(ecx, ptr);
11681192

11691193
rel.map(|(alloc_id, size)| {
11701194
let tag = match ptr.provenance {

tests/mir-opt/inline/unit_test.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Check that `-Zmir-enable-passes=+Inline` does not ICE because of stolen MIR.
2+
// unit-test: Inline
3+
// skip-filecheck
4+
#![crate_type = "lib"]
5+
6+
// Randomize `def_path_hash` by defining them under a module with different names
7+
macro_rules! emit {
8+
($($m:ident)*) => {$(
9+
pub mod $m {
10+
pub fn main() {
11+
let func = || 123u8;
12+
func();
13+
}
14+
}
15+
)*};
16+
}
17+
18+
// Increase the chance of triggering the bug
19+
emit!(m00 m01 m02 m03 m04 m05 m06 m07 m08 m09 m10 m11 m12 m13 m14 m15 m16 m17 m18 m19);

0 commit comments

Comments
 (0)