From 903bb97c17ebe49204a8118ee742f87e74c8dae9 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 13 Sep 2016 13:03:42 +0200 Subject: [PATCH 1/3] needless references --- src/interpreter/step.rs | 2 +- src/interpreter/vtable.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interpreter/step.rs b/src/interpreter/step.rs index 2509aba0900..7eaf92c9b5a 100644 --- a/src/interpreter/step.rs +++ b/src/interpreter/step.rs @@ -30,7 +30,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { let mir = self.mir(); let basic_block = &mir.basic_blocks()[block]; - if let Some(ref stmt) = basic_block.statements.get(stmt_id) { + if let Some(stmt) = basic_block.statements.get(stmt_id) { let mut new = Ok(0); ConstantExtractor { span: stmt.source_info.span, diff --git a/src/interpreter/vtable.rs b/src/interpreter/vtable.rs index edcdccf346c..6a3de7aae80 100644 --- a/src/interpreter/vtable.rs +++ b/src/interpreter/vtable.rs @@ -164,7 +164,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { // method could then never be called, so we do not want to // try and trans it, in that case. Issue #23435. if mth.is_provided { - let predicates = mth.method.predicates.predicates.subst(self.tcx, &mth.substs); + let predicates = mth.method.predicates.predicates.subst(self.tcx, mth.substs); if !self.normalize_and_test_predicates(predicates) { debug!("get_vtable_methods: predicates do not hold"); return None; From c57233abca7c2f89ea656bfc05e80d745b07369b Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 13 Sep 2016 13:03:54 +0200 Subject: [PATCH 2/3] needless clones --- src/interpreter/vtable.rs | 4 ++-- src/memory.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/interpreter/vtable.rs b/src/interpreter/vtable.rs index 6a3de7aae80..726c6ce3913 100644 --- a/src/interpreter/vtable.rs +++ b/src/interpreter/vtable.rs @@ -20,8 +20,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { debug!("get_vtable(trait_ref={:?})", trait_ref); - let methods: Vec<_> = traits::supertraits(tcx, trait_ref.clone()).flat_map(|trait_ref| { - match self.fulfill_obligation(trait_ref.clone()) { + let methods: Vec<_> = traits::supertraits(tcx, trait_ref).flat_map(|trait_ref| { + match self.fulfill_obligation(trait_ref) { // Should default trait error here? traits::VtableDefaultImpl(_) | traits::VtableBuiltin(_) => { diff --git a/src/memory.rs b/src/memory.rs index c02ea22c1d9..79b4b8b64d6 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -314,7 +314,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> { Some(&FunctionDefinition { def_id, kind: FunctionKind::Closure { ref substs, ref ty } - }) => Ok((def_id, substs.clone(), ty.clone())), + }) => Ok((def_id, *substs, ty.clone())), Some(&FunctionDefinition { kind: FunctionKind::Function { .. }, .. }) => Err(EvalError::CalledClosureAsFunction), From 23eb8a5cf2053f65d629e0ea6a65aa9560a2f708 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 13 Sep 2016 13:08:57 +0200 Subject: [PATCH 3/3] error on failed assumptions --- src/error.rs | 3 +++ src/interpreter/terminator.rs | 7 +++++-- tests/compile-fail/assume.rs | 10 ++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 tests/compile-fail/assume.rs diff --git a/src/error.rs b/src/error.rs index e9312a1ef3e..5624734e888 100644 --- a/src/error.rs +++ b/src/error.rs @@ -43,6 +43,7 @@ pub enum EvalError<'tcx> { CalledClosureAsFunction, VtableForArgumentlessMethod, ModifiedConstantMemory, + AssumptionNotHeld, } pub type EvalResult<'tcx, T> = Result>; @@ -97,6 +98,8 @@ impl<'tcx> Error for EvalError<'tcx> { "tried to call a vtable function without arguments", EvalError::ModifiedConstantMemory => "tried to modify constant memory", + EvalError::AssumptionNotHeld => + "`assume` argument was false" } } diff --git a/src/interpreter/terminator.rs b/src/interpreter/terminator.rs index 9984e1f14ea..23396e0694e 100644 --- a/src/interpreter/terminator.rs +++ b/src/interpreter/terminator.rs @@ -284,8 +284,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { "sub_with_overflow" => self.intrinsic_with_overflow(mir::BinOp::Sub, &args[0], &args[1], dest, dest_layout)?, "mul_with_overflow" => self.intrinsic_with_overflow(mir::BinOp::Mul, &args[0], &args[1], dest, dest_layout)?, - // FIXME: turn into an assertion to catch wrong `assume` that would cause UB in llvm - "assume" => {} + "assume" => { + if !self.memory.read_bool(args_ptrs[0])? { + return Err(EvalError::AssumptionNotHeld); + } + } "copy_nonoverlapping" => { let elem_ty = substs.type_at(0); diff --git a/tests/compile-fail/assume.rs b/tests/compile-fail/assume.rs new file mode 100644 index 00000000000..69758a5d7fe --- /dev/null +++ b/tests/compile-fail/assume.rs @@ -0,0 +1,10 @@ +#![feature(core_intrinsics)] + +fn main() { + let x = 5; + unsafe { + std::intrinsics::assume(x < 10); + std::intrinsics::assume(x > 1); + std::intrinsics::assume(x > 42); //~ ERROR: `assume` argument was false + } +}