fix the block processing for the drop_in_place intrinsic

This commit is contained in:
Oliver Schneider 2016-11-04 17:51:13 +01:00
parent 893f16389e
commit 07c752cc82
No known key found for this signature in database
GPG key ID: 56D6EEA0FC67AC46
3 changed files with 31 additions and 3 deletions

View file

@ -18,6 +18,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
dest: Lvalue<'tcx>,
dest_ty: Ty<'tcx>,
dest_layout: &'tcx Layout,
target: mir::BasicBlock,
) -> EvalResult<'tcx, ()> {
let arg_vals: EvalResult<Vec<Value>> = args.iter()
.map(|arg| self.eval_operand(arg))
@ -137,7 +138,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
};
let mut drops = Vec::new();
self.drop(lvalue, ty, &mut drops)?;
self.eval_drop_impls(drops)?;
// need to change the block before pushing the drop impl stack frames
// we could do this for all intrinsics before evaluating the intrinsics, but if
// the evaluation fails, we should not have moved forward
self.goto_block(target);
return self.eval_drop_impls(drops);
}
"fabsf32" => {
@ -341,6 +346,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
name => return Err(EvalError::Unimplemented(format!("unimplemented intrinsic: {}", name))),
}
self.goto_block(target);
// Since we pushed no stack frame, the main loop will act
// as if the call just completed and it's returning to the
// current frame.

View file

@ -187,8 +187,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let ty = fn_ty.sig.0.output;
let layout = self.type_layout(ty);
let (ret, target) = destination.unwrap();
self.call_intrinsic(def_id, substs, arg_operands, ret, ty, layout)?;
self.goto_block(target);
self.call_intrinsic(def_id, substs, arg_operands, ret, ty, layout, target)?;
Ok(())
}

View file

@ -0,0 +1,22 @@
trait Foo {}
struct Bar;
static mut DROP_CALLED: bool = false;
impl Drop for Bar {
fn drop(&mut self) {
unsafe { DROP_CALLED = true; }
}
}
impl Foo for Bar {}
use std::rc::Rc;
fn main() {
let b: Rc<Foo> = Rc::new(Bar);
assert!(unsafe { !DROP_CALLED });
drop(b);
assert!(unsafe { DROP_CALLED });
}