Skip to content

Commit b44babf

Browse files
committed
allocate return pointer only when we start the program via the start lang item
1 parent b8e0b79 commit b44babf

File tree

1 file changed

+15
-13
lines changed

1 file changed

+15
-13
lines changed

src/eval_context.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,6 +1689,7 @@ pub fn eval_main<'a, 'tcx: 'a>(
16891689
) -> EvalResult<'tcx> {
16901690
let main_instance = ty::Instance::mono(ecx.tcx, main_id);
16911691
let main_mir = ecx.load_mir(main_instance.def)?;
1692+
let mut cleanup_ptr = None; // Pointer to be deallocated when we are done
16921693

16931694
if !main_mir.return_ty.is_nil() || main_mir.arg_count != 0 {
16941695
return Err(EvalError::Unimplemented("miri does not support main functions without `fn()` type signatures".to_owned()));
@@ -1702,12 +1703,22 @@ pub fn eval_main<'a, 'tcx: 'a>(
17021703
return Err(EvalError::AbiViolation(format!("'start' lang item should have three arguments, but has {}", start_mir.arg_count)));
17031704
}
17041705

1706+
// Return value
1707+
let ret_ptr = {
1708+
let ty = ecx.tcx.types.isize;
1709+
let layout = ecx.type_layout_with_substs(ty, Substs::empty())?;
1710+
let size = layout.size(&ecx.tcx.data_layout).bytes();
1711+
let align = layout.align(&ecx.tcx.data_layout).abi();
1712+
ecx.memory.allocate(size, align)?
1713+
};
1714+
cleanup_ptr = Some(ret_ptr);
1715+
17051716
// Push our stack frame
17061717
ecx.push_stack_frame(
17071718
start_instance,
17081719
start_mir.span,
17091720
start_mir,
1710-
Lvalue::from_ptr(Pointer::zst_ptr()), // we'll fix the return lvalue later
1721+
Lvalue::from_ptr(ret_ptr),
17111722
StackPopCleanup::None,
17121723
)?;
17131724

@@ -1739,19 +1750,10 @@ pub fn eval_main<'a, 'tcx: 'a>(
17391750
)?;
17401751
}
17411752

1742-
// Allocate memory for the return value. We have to do this when a stack frame was already pushed as the type code below
1743-
// calls EvalContext::substs, which needs a frame to be allocated (?!?)
1744-
let ret_ptr = {
1745-
let ty = ecx.tcx.types.isize;
1746-
let layout = ecx.type_layout(ty)?;
1747-
let size = layout.size(&ecx.tcx.data_layout).bytes();
1748-
let align = layout.align(&ecx.tcx.data_layout).abi();
1749-
ecx.memory.allocate(size, align)?
1750-
};
1751-
ecx.frame_mut().return_lvalue = Lvalue::from_ptr(ret_ptr);
1752-
17531753
while ecx.step()? {}
1754-
ecx.memory.deallocate(ret_ptr)?;
1754+
if let Some(cleanup_ptr) = cleanup_ptr {
1755+
ecx.memory.deallocate(cleanup_ptr)?;
1756+
}
17551757
return Ok(());
17561758
}
17571759

0 commit comments

Comments
 (0)