Skip to content

Commit b91bf7a

Browse files
committed
miri: couple ret place and ret block together (they both exist or both don't)
1 parent 419d3fc commit b91bf7a

File tree

5 files changed

+65
-67
lines changed

5 files changed

+65
-67
lines changed

src/librustc_mir/const_eval.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
323323
ecx: &mut InterpCx<'mir, 'tcx, Self>,
324324
instance: ty::Instance<'tcx>,
325325
args: &[OpTy<'tcx>],
326-
dest: Option<PlaceTy<'tcx>>,
327-
ret: Option<mir::BasicBlock>,
326+
ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
328327
_unwind: Option<mir::BasicBlock> // unwinding is not supported in consts
329328
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
330329
debug!("eval_fn_call: {:?}", instance);
@@ -337,8 +336,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
337336
// Some functions we support even if they are non-const -- but avoid testing
338337
// that for const fn! We certainly do *not* want to actually call the fn
339338
// though, so be sure we return here.
340-
return if ecx.hook_panic_fn(instance, args, dest)? {
341-
ecx.return_to_block(ret)?; // callee is fully evaluated and done
339+
return if ecx.hook_panic_fn(instance, args, ret)? {
342340
Ok(None)
343341
} else {
344342
throw_unsup_format!("calling non-const function `{}`", instance)
@@ -364,8 +362,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
364362
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
365363
fn_val: !,
366364
_args: &[OpTy<'tcx>],
367-
_dest: Option<PlaceTy<'tcx>>,
368-
_ret: Option<mir::BasicBlock>,
365+
_ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
366+
_unwind: Option<mir::BasicBlock>
369367
) -> InterpResult<'tcx> {
370368
match fn_val {}
371369
}
@@ -375,11 +373,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
375373
span: Span,
376374
instance: ty::Instance<'tcx>,
377375
args: &[OpTy<'tcx>],
378-
dest: Option<PlaceTy<'tcx>>,
379-
_ret: Option<mir::BasicBlock>,
376+
ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
380377
_unwind: Option<mir::BasicBlock>
381378
) -> InterpResult<'tcx> {
382-
if ecx.emulate_intrinsic(span, instance, args, dest)? {
379+
if ecx.emulate_intrinsic(span, instance, args, ret)? {
383380
return Ok(());
384381
}
385382
// An intrinsic that we do not support

src/librustc_mir/interpret/intrinsics.rs

+37-28
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ use rustc::ty::layout::{LayoutOf, Primitive, Size};
99
use rustc::ty::subst::SubstsRef;
1010
use rustc::hir::def_id::DefId;
1111
use rustc::ty::TyCtxt;
12-
use rustc::mir::BinOp;
13-
use rustc::mir::interpret::{InterpResult, Scalar, GlobalId, ConstValue};
12+
use rustc::mir::{
13+
self, BinOp,
14+
interpret::{InterpResult, Scalar, GlobalId, ConstValue}
15+
};
1416

1517
use super::{
1618
Machine, PlaceTy, OpTy, InterpCx, ImmTy,
@@ -91,13 +93,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
9193
span: Span,
9294
instance: ty::Instance<'tcx>,
9395
args: &[OpTy<'tcx, M::PointerTag>],
94-
dest: Option<PlaceTy<'tcx, M::PointerTag>>,
96+
ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
9597
) -> InterpResult<'tcx, bool> {
9698
let substs = instance.substs;
9799

98100
// We currently do not handle any diverging intrinsics.
99-
let dest = match dest {
100-
Some(dest) => dest,
101+
let (dest, ret) = match ret {
102+
Some(p) => p,
101103
None => return Ok(false)
102104
};
103105
let intrinsic_name = &*self.tcx.item_name(instance.def_id()).as_str();
@@ -268,34 +270,39 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
268270
// exception from the exception.)
269271
// This is the dual to the special exception for offset-by-0
270272
// in the inbounds pointer offset operation (see the Miri code, `src/operator.rs`).
271-
if a.is_bits() && b.is_bits() {
273+
//
274+
// Control flow is weird because we cannot early-return (to reach the
275+
// `go_to_block` at the end).
276+
let done = if a.is_bits() && b.is_bits() {
272277
let a = a.to_machine_usize(self)?;
273278
let b = b.to_machine_usize(self)?;
274279
if a == b && a != 0 {
275280
self.write_scalar(Scalar::from_int(0, isize_layout.size), dest)?;
276-
return Ok(true);
277-
}
278-
}
281+
true
282+
} else { false }
283+
} else { false };
279284

280-
// General case: we need two pointers.
281-
let a = self.force_ptr(a)?;
282-
let b = self.force_ptr(b)?;
283-
if a.alloc_id != b.alloc_id {
284-
throw_ub_format!(
285-
"ptr_offset_from cannot compute offset of pointers into different \
286-
allocations.",
287-
);
285+
if !done {
286+
// General case: we need two pointers.
287+
let a = self.force_ptr(a)?;
288+
let b = self.force_ptr(b)?;
289+
if a.alloc_id != b.alloc_id {
290+
throw_ub_format!(
291+
"ptr_offset_from cannot compute offset of pointers into different \
292+
allocations.",
293+
);
294+
}
295+
let usize_layout = self.layout_of(self.tcx.types.usize)?;
296+
let a_offset = ImmTy::from_uint(a.offset.bytes(), usize_layout);
297+
let b_offset = ImmTy::from_uint(b.offset.bytes(), usize_layout);
298+
let (val, _overflowed, _ty) = self.overflowing_binary_op(
299+
BinOp::Sub, a_offset, b_offset,
300+
)?;
301+
let pointee_layout = self.layout_of(substs.type_at(0))?;
302+
let val = ImmTy::from_scalar(val, isize_layout);
303+
let size = ImmTy::from_int(pointee_layout.size.bytes(), isize_layout);
304+
self.exact_div(val, size, dest)?;
288305
}
289-
let usize_layout = self.layout_of(self.tcx.types.usize)?;
290-
let a_offset = ImmTy::from_uint(a.offset.bytes(), usize_layout);
291-
let b_offset = ImmTy::from_uint(b.offset.bytes(), usize_layout);
292-
let (val, _overflowed, _ty) = self.overflowing_binary_op(
293-
BinOp::Sub, a_offset, b_offset,
294-
)?;
295-
let pointee_layout = self.layout_of(substs.type_at(0))?;
296-
let val = ImmTy::from_scalar(val, isize_layout);
297-
let size = ImmTy::from_int(pointee_layout.size.bytes(), isize_layout);
298-
self.exact_div(val, size, dest)?;
299306
}
300307

301308
"transmute" => {
@@ -350,6 +357,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
350357
_ => return Ok(false),
351358
}
352359

360+
self.dump_place(*dest);
361+
self.go_to_block(ret);
353362
Ok(true)
354363
}
355364

@@ -360,7 +369,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
360369
&mut self,
361370
instance: ty::Instance<'tcx>,
362371
args: &[OpTy<'tcx, M::PointerTag>],
363-
_dest: Option<PlaceTy<'tcx, M::PointerTag>>,
372+
_ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
364373
) -> InterpResult<'tcx, bool> {
365374
let def_id = instance.def_id();
366375
if Some(def_id) == self.tcx.lang_items().panic_fn() {

src/librustc_mir/interpret/machine.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,8 @@ pub trait Machine<'mir, 'tcx>: Sized {
150150
ecx: &mut InterpCx<'mir, 'tcx, Self>,
151151
instance: ty::Instance<'tcx>,
152152
args: &[OpTy<'tcx, Self::PointerTag>],
153-
dest: Option<PlaceTy<'tcx, Self::PointerTag>>,
154-
ret: Option<mir::BasicBlock>,
155-
unwind: Option<mir::BasicBlock>
153+
ret: Option<(PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
154+
unwind: Option<mir::BasicBlock>,
156155
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>>;
157156

158157
/// Execute `fn_val`. It is the hook's responsibility to advance the instruction
@@ -161,8 +160,8 @@ pub trait Machine<'mir, 'tcx>: Sized {
161160
ecx: &mut InterpCx<'mir, 'tcx, Self>,
162161
fn_val: Self::ExtraFnVal,
163162
args: &[OpTy<'tcx, Self::PointerTag>],
164-
dest: Option<PlaceTy<'tcx, Self::PointerTag>>,
165-
ret: Option<mir::BasicBlock>,
163+
ret: Option<(PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
164+
unwind: Option<mir::BasicBlock>,
166165
) -> InterpResult<'tcx>;
167166

168167
/// Directly process an intrinsic without pushing a stack frame. It is the hook's
@@ -172,8 +171,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
172171
span: Span,
173172
instance: ty::Instance<'tcx>,
174173
args: &[OpTy<'tcx, Self::PointerTag>],
175-
dest: Option<PlaceTy<'tcx, Self::PointerTag>>,
176-
ret: Option<mir::BasicBlock>,
174+
ret: Option<(PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
177175
unwind: Option<mir::BasicBlock>,
178176
) -> InterpResult<'tcx>;
179177

src/librustc_mir/interpret/terminator.rs

+13-17
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
5959
ref cleanup,
6060
..
6161
} => {
62-
let (dest, ret) = match *destination {
63-
Some((ref lv, target)) => (Some(self.eval_place(lv)?), Some(target)),
64-
None => (None, None),
65-
};
66-
6762
let func = self.eval_operand(func, None)?;
6863
let (fn_val, abi) = match func.layout.ty.kind {
6964
ty::FnPtr(sig) => {
@@ -81,12 +76,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
8176
}
8277
};
8378
let args = self.eval_operands(args)?;
79+
let ret = match destination {
80+
Some((dest, ret)) => Some((self.eval_place(dest)?, *ret)),
81+
None => None,
82+
};
8483
self.eval_fn_call(
8584
fn_val,
8685
terminator.source_info.span,
8786
abi,
8887
&args[..],
89-
dest,
9088
ret,
9189
*cleanup
9290
)?;
@@ -238,16 +236,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
238236
span: Span,
239237
caller_abi: Abi,
240238
args: &[OpTy<'tcx, M::PointerTag>],
241-
dest: Option<PlaceTy<'tcx, M::PointerTag>>,
242-
ret: Option<mir::BasicBlock>,
239+
ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
243240
unwind: Option<mir::BasicBlock>
244241
) -> InterpResult<'tcx> {
245242
trace!("eval_fn_call: {:#?}", fn_val);
246243

247244
let instance = match fn_val {
248245
FnVal::Instance(instance) => instance,
249246
FnVal::Other(extra) => {
250-
return M::call_extra_fn(self, extra, args, dest, ret);
247+
return M::call_extra_fn(self, extra, args, ret, unwind);
251248
}
252249
};
253250

@@ -278,7 +275,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
278275
match instance.def {
279276
ty::InstanceDef::Intrinsic(..) => {
280277
assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic);
281-
return M::call_intrinsic(self, span, instance, args, dest, ret, unwind);
278+
return M::call_intrinsic(self, span, instance, args, ret, unwind);
282279
}
283280
ty::InstanceDef::VtableShim(..) |
284281
ty::InstanceDef::ReifyShim(..) |
@@ -288,7 +285,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
288285
ty::InstanceDef::CloneShim(..) |
289286
ty::InstanceDef::Item(_) => {
290287
// We need MIR for this fn
291-
let body = match M::find_fn(self, instance, args, dest, ret, unwind)? {
288+
let body = match M::find_fn(self, instance, args, ret, unwind)? {
292289
Some(body) => body,
293290
None => return Ok(()),
294291
};
@@ -297,8 +294,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
297294
instance,
298295
span,
299296
body,
300-
dest,
301-
StackPopCleanup::Goto { ret, unwind }
297+
ret.map(|p| p.0),
298+
StackPopCleanup::Goto { ret: ret.map(|p| p.1), unwind }
302299
)?;
303300

304301
// We want to pop this frame again in case there was an error, to put
@@ -381,7 +378,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
381378
throw_unsup!(FunctionArgCountMismatch)
382379
}
383380
// Don't forget to check the return type!
384-
if let Some(caller_ret) = dest {
381+
if let Some((caller_ret, _)) = ret {
385382
let callee_ret = self.eval_place(
386383
&mir::Place::return_place()
387384
)?;
@@ -447,7 +444,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
447444
});
448445
trace!("Patched self operand to {:#?}", args[0]);
449446
// recurse with concrete function
450-
self.eval_fn_call(drop_fn, span, caller_abi, &args, dest, ret, unwind)
447+
self.eval_fn_call(drop_fn, span, caller_abi, &args, ret, unwind)
451448
}
452449
}
453450
}
@@ -487,8 +484,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
487484
span,
488485
Abi::Rust,
489486
&[arg.into()],
490-
Some(dest.into()),
491-
Some(target),
487+
Some((dest.into(), target)),
492488
unwind
493489
)
494490
}

src/librustc_mir/transform/const_prop.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
144144
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
145145
_instance: ty::Instance<'tcx>,
146146
_args: &[OpTy<'tcx>],
147-
_dest: Option<PlaceTy<'tcx>>,
148-
_ret: Option<BasicBlock>,
147+
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
149148
_unwind: Option<BasicBlock>,
150149
) -> InterpResult<'tcx, Option<&'mir Body<'tcx>>> {
151150
Ok(None)
@@ -155,8 +154,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
155154
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
156155
fn_val: !,
157156
_args: &[OpTy<'tcx>],
158-
_dest: Option<PlaceTy<'tcx>>,
159-
_ret: Option<BasicBlock>,
157+
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
158+
_unwind: Option<BasicBlock>
160159
) -> InterpResult<'tcx> {
161160
match fn_val {}
162161
}
@@ -166,8 +165,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
166165
_span: Span,
167166
_instance: ty::Instance<'tcx>,
168167
_args: &[OpTy<'tcx>],
169-
_dest: Option<PlaceTy<'tcx>>,
170-
_ret: Option<BasicBlock>,
168+
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
171169
_unwind: Option<BasicBlock>
172170
) -> InterpResult<'tcx> {
173171
throw_unsup_format!("calling intrinsics isn't supported in ConstProp");

0 commit comments

Comments
 (0)