Skip to content

Commit 3bf51f5

Browse files
committed
Auto merge of #1077 - RalfJung:unwind_to_block, r=RalfJung
adjust for goto_block refactoring The Miri side of rust-lang/rust#66646
2 parents 91cec06 + a04620e commit 3bf51f5

File tree

8 files changed

+46
-55
lines changed

8 files changed

+46
-55
lines changed

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
bd816fd76f4f7a040ca7ac8ca5bc556d761f96fa
1+
809e180a76ce97340bf4354ff357bc59e3ca40b2

src/eval.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,16 +201,18 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) ->
201201
// Process the result.
202202
match res {
203203
Ok(return_code) => {
204-
let leaks = ecx.memory.leak_report();
205204
// Disable the leak test on some platforms where we do not
206205
// correctly implement TLS destructors.
207206
let target_os = ecx.tcx.tcx.sess.target.target.target_os.to_lowercase();
208207
let ignore_leaks = target_os == "windows" || target_os == "macos";
209-
if !ignore_leaks && leaks != 0 {
210-
tcx.sess.err("the evaluated program leaked memory");
211-
// Ignore the provided return code - let the reported error
212-
// determine the return code.
213-
return None;
208+
if !ignore_leaks {
209+
let leaks = ecx.memory.leak_report();
210+
if leaks != 0 {
211+
tcx.sess.err("the evaluated program leaked memory");
212+
// Ignore the provided return code - let the reported error
213+
// determine the return code.
214+
return None;
215+
}
214216
}
215217
return Some(return_code)
216218
}

src/machine.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -186,22 +186,21 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
186186
ecx: &mut InterpCx<'mir, 'tcx, Self>,
187187
instance: ty::Instance<'tcx>,
188188
args: &[OpTy<'tcx, Tag>],
189-
dest: Option<PlaceTy<'tcx, Tag>>,
190-
ret: Option<mir::BasicBlock>,
189+
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
191190
unwind: Option<mir::BasicBlock>,
192191
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
193-
ecx.find_fn(instance, args, dest, ret, unwind)
192+
ecx.find_fn(instance, args, ret, unwind)
194193
}
195194

196195
#[inline(always)]
197196
fn call_extra_fn(
198197
ecx: &mut InterpCx<'mir, 'tcx, Self>,
199198
fn_val: Dlsym,
200199
args: &[OpTy<'tcx, Tag>],
201-
dest: Option<PlaceTy<'tcx, Tag>>,
202-
ret: Option<mir::BasicBlock>,
200+
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
201+
_unwind: Option<mir::BasicBlock>,
203202
) -> InterpResult<'tcx> {
204-
ecx.call_dlsym(fn_val, args, dest, ret)
203+
ecx.call_dlsym(fn_val, args, ret)
205204
}
206205

207206
#[inline(always)]
@@ -210,11 +209,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
210209
span: Span,
211210
instance: ty::Instance<'tcx>,
212211
args: &[OpTy<'tcx, Tag>],
213-
dest: Option<PlaceTy<'tcx, Tag>>,
214-
ret: Option<mir::BasicBlock>,
212+
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
215213
unwind: Option<mir::BasicBlock>,
216214
) -> InterpResult<'tcx> {
217-
ecx.call_intrinsic(span, instance, args, dest, ret, unwind)
215+
ecx.call_intrinsic(span, instance, args, ret, unwind)
218216
}
219217

220218
#[inline(always)]

src/shims/dlsym.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
2727
&mut self,
2828
dlsym: Dlsym,
2929
args: &[OpTy<'tcx, Tag>],
30-
dest: Option<PlaceTy<'tcx, Tag>>,
31-
ret: Option<mir::BasicBlock>,
30+
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
3231
) -> InterpResult<'tcx> {
3332
use self::Dlsym::*;
3433

3534
let this = self.eval_context_mut();
36-
37-
let dest = dest.expect("we don't support any diverging dlsym");
38-
let ret = ret.expect("dest is `Some` but ret is `None`");
35+
let (dest, ret) = ret.expect("we don't support any diverging dlsym");
3936

4037
match dlsym {
4138
GetEntropy => {
@@ -46,8 +43,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
4643
}
4744
}
4845

49-
this.goto_block(Some(ret))?;
5046
this.dump_place(*dest);
47+
this.go_to_block(ret);
5148
Ok(())
5249
}
5350
}

src/shims/foreign_items.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
114114
&mut self,
115115
def_id: DefId,
116116
args: &[OpTy<'tcx, Tag>],
117-
dest: Option<PlaceTy<'tcx, Tag>>,
118-
ret: Option<mir::BasicBlock>,
117+
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
119118
_unwind: Option<mir::BasicBlock>
120119
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
121120
let this = self.eval_context_mut();
@@ -129,7 +128,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
129128
let tcx = &{ this.tcx.tcx };
130129

131130
// First: functions that diverge.
132-
match link_name {
131+
let (dest, ret) = match link_name {
133132
// Note that this matches calls to the *foreign* item `__rust_start_panic* -
134133
// that is, calls to `extern "Rust" { fn __rust_start_panic(...) }`.
135134
// We forward this to the underlying *implementation* in the panic runtime crate.
@@ -154,15 +153,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
154153
return Err(InterpError::Exit(code).into());
155154
}
156155
_ => {
157-
if dest.is_none() {
156+
if let Some(p) = ret {
157+
p
158+
} else {
158159
throw_unsup_format!("can't call (diverging) foreign function: {}", link_name);
159160
}
160161
}
161-
}
162+
};
162163

163-
// Next: functions that assume a ret and dest.
164-
let dest = dest.expect("we already checked for a dest");
165-
let ret = ret.expect("dest is `Some` but ret is `None`");
164+
// Next: functions that return.
166165
match link_name {
167166
"malloc" => {
168167
let size = this.read_scalar(args[0])?.to_machine_usize(this)?;
@@ -928,8 +927,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
928927
_ => throw_unsup_format!("can't call foreign function: {}", link_name),
929928
}
930929

931-
this.goto_block(Some(ret))?;
932930
this.dump_place(*dest);
931+
this.go_to_block(ret);
933932
Ok(None)
934933
}
935934

src/shims/intrinsics.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1616
span: Span,
1717
instance: ty::Instance<'tcx>,
1818
args: &[OpTy<'tcx, Tag>],
19-
dest: Option<PlaceTy<'tcx, Tag>>,
20-
_ret: Option<mir::BasicBlock>,
19+
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
2120
unwind: Option<mir::BasicBlock>
2221
) -> InterpResult<'tcx> {
2322
let this = self.eval_context_mut();
24-
if this.emulate_intrinsic(span, instance, args, dest)? {
23+
if this.emulate_intrinsic(span, instance, args, ret)? {
2524
return Ok(());
2625
}
2726
let tcx = &{this.tcx.tcx};
@@ -32,23 +31,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
3231
// that might still hang around!
3332
let intrinsic_name = &*tcx.item_name(instance.def_id()).as_str();
3433

35-
// Handle diverging intrinsics
36-
match intrinsic_name {
34+
// Handle diverging intrinsics.
35+
let (dest, ret) = match intrinsic_name {
3736
"abort" => {
3837
// FIXME: Add a better way of indicating 'abnormal' termination,
3938
// since this is not really an 'unsupported' behavior
4039
throw_unsup_format!("the evaluated program aborted!");
4140
}
4241
"miri_start_panic" => return this.handle_miri_start_panic(args, unwind),
43-
_ => {}
44-
}
45-
46-
// Handle non-diverging intrinsics
47-
// The intrinsic itself cannot diverge (otherwise, we would have handled it above),
48-
// so if we got here without a return place that's UB (can happen e.g., for transmute returning `!`).
49-
let dest = match dest {
50-
Some(dest) => dest,
51-
None => throw_ub!(Unreachable)
42+
_ => {
43+
if let Some(p) = ret {
44+
p
45+
} else {
46+
throw_unsup_format!("unimplemented (diverging) intrinsic: {}", intrinsic_name);
47+
}
48+
}
5249
};
5350

5451
match intrinsic_name {
@@ -581,6 +578,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
581578
name => throw_unsup_format!("unimplemented intrinsic: {}", name),
582579
}
583580

581+
this.dump_place(*dest);
582+
this.go_to_block(ret);
584583
Ok(())
585584
}
586585
}

src/shims/mod.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,24 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1616
&mut self,
1717
instance: ty::Instance<'tcx>,
1818
args: &[OpTy<'tcx, Tag>],
19-
dest: Option<PlaceTy<'tcx, Tag>>,
20-
ret: Option<mir::BasicBlock>,
19+
ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
2120
unwind: Option<mir::BasicBlock>
2221
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
2322
let this = self.eval_context_mut();
2423
trace!(
2524
"eval_fn_call: {:#?}, {:?}",
2625
instance,
27-
dest.map(|place| *place)
26+
ret.map(|p| *p.0)
2827
);
2928

3029
// There are some more lang items we want to hook that CTFE does not hook (yet).
3130
if this.tcx.lang_items().align_offset_fn() == Some(instance.def.def_id()) {
32-
let dest = dest.unwrap();
31+
let (dest, ret) = ret.unwrap();
3332
let n = this
3433
.align_offset(args[0], args[1])?
3534
.unwrap_or_else(|| this.truncate(u128::max_value(), dest.layout));
3635
this.write_scalar(Scalar::from_uint(n, dest.layout.size), dest)?;
37-
this.goto_block(ret)?;
36+
this.go_to_block(ret);
3837
return Ok(None);
3938
}
4039

@@ -46,7 +45,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
4645
// to run extra MIR), and Ok(Some(body)) if we found MIR to run for the
4746
// foreign function
4847
// Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
49-
return this.emulate_foreign_item(instance.def_id(), args, dest, ret, unwind);
48+
return this.emulate_foreign_item(instance.def_id(), args, ret, unwind);
5049
}
5150

5251
// Otherwise, load the MIR.

src/shims/panic.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5353
this.machine.panic_payload = Some(scalar);
5454

5555
// Jump to the unwind block to begin unwinding.
56-
// We don't use `goto_block` as that is just meant for normal returns.
57-
let next_frame = this.frame_mut();
58-
next_frame.block = unwind;
59-
next_frame.stmt = 0;
56+
this.unwind_to_block(unwind);
6057
return Ok(())
6158
}
6259

0 commit comments

Comments
 (0)