Skip to content

Commit 6f5529a

Browse files
authored
Merge branch 'master' into patch-1
2 parents 03eff59 + e4b298b commit 6f5529a

18 files changed

+176
-27
lines changed

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
d8f50ab0ea6c529c24e575279acc72093caeb679
1+
374c63e0fc356eb61b1966cb6026a2a49fe9226d

src/bin/miri-rustc-tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
4343
compiler.session().abort_if_errors();
4444
compiler.global_ctxt().unwrap().peek_mut().enter(|tcx| {
4545
if std::env::args().any(|arg| arg == "--test") {
46-
struct Visitor<'tcx>(TyCtxt<'tcx, 'tcx>);
46+
struct Visitor<'tcx>(TyCtxt<'tcx>);
4747
impl<'tcx, 'hir> itemlikevisit::ItemLikeVisitor<'hir> for Visitor<'tcx> {
4848
fn visit_item(&mut self, i: &'hir hir::Item) {
4949
if let hir::ItemKind::Fn(.., body_id) = i.node {

src/fn_call.rs

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -560,18 +560,56 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
560560
let n = this.memory().get(ptr.alloc_id)?.read_c_str(tcx, ptr)?.len();
561561
this.write_scalar(Scalar::from_uint(n as u64, dest.layout.size), dest)?;
562562
}
563-
"cbrt" => {
563+
564+
// math functions
565+
566+
"cbrtf" | "coshf" | "sinhf" |"tanf" => {
567+
// FIXME: Using host floats.
568+
let f = f32::from_bits(this.read_scalar(args[0])?.to_u32()?);
569+
let f = match link_name {
570+
"cbrtf" => f.cbrt(),
571+
"coshf" => f.cosh(),
572+
"sinhf" => f.sinh(),
573+
"tanf" => f.tan(),
574+
_ => bug!(),
575+
};
576+
this.write_scalar(Scalar::from_u32(f.to_bits()), dest)?;
577+
}
578+
// underscore case for windows
579+
"_hypotf" | "hypotf" | "atan2f" => {
580+
// FIXME: Using host floats.
581+
let f1 = f32::from_bits(this.read_scalar(args[0])?.to_u32()?);
582+
let f2 = f32::from_bits(this.read_scalar(args[1])?.to_u32()?);
583+
let n = match link_name {
584+
"_hypotf" | "hypotf" => f1.hypot(f2),
585+
"atan2f" => f1.atan2(f2),
586+
_ => bug!(),
587+
};
588+
this.write_scalar(Scalar::from_u32(n.to_bits()), dest)?;
589+
}
590+
591+
"cbrt" | "cosh" | "sinh" | "tan" => {
564592
// FIXME: Using host floats.
565593
let f = f64::from_bits(this.read_scalar(args[0])?.to_u64()?);
566-
let n = f.cbrt();
567-
this.write_scalar(Scalar::from_u64(n.to_bits()), dest)?;
594+
let f = match link_name {
595+
"cbrt" => f.cbrt(),
596+
"cosh" => f.cosh(),
597+
"sinh" => f.sinh(),
598+
"tan" => f.tan(),
599+
_ => bug!(),
600+
};
601+
this.write_scalar(Scalar::from_u64(f.to_bits()), dest)?;
568602
}
569603
// underscore case for windows
570-
"_hypot" | "hypot" => {
604+
"_hypot" | "hypot" | "atan2" => {
571605
// FIXME: Using host floats.
572606
let f1 = f64::from_bits(this.read_scalar(args[0])?.to_u64()?);
573607
let f2 = f64::from_bits(this.read_scalar(args[1])?.to_u64()?);
574-
let n = f1.hypot(f2);
608+
let n = match link_name {
609+
"_hypot" | "hypot" => f1.hypot(f2),
610+
"atan2" => f1.atan2(f2),
611+
_ => bug!(),
612+
};
575613
this.write_scalar(Scalar::from_u64(n.to_bits()), dest)?;
576614
}
577615

src/intrinsic.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
272272
let b = this.read_immediate(args[1])?;
273273
// check x % y != 0
274274
if this.binary_op(mir::BinOp::Rem, a, b)?.0.to_bits(dest.layout.size)? != 0 {
275-
return err!(ValidationFailure(format!("exact_div: {:?} cannot be divided by {:?}", a, b)));
275+
// Check if `b` is -1, which is the "min_value / -1" case.
276+
let minus1 = Scalar::from_int(-1, dest.layout.size);
277+
return if b.to_scalar().unwrap() == minus1 {
278+
err!(Intrinsic(format!("exact_div: result of dividing MIN by -1 cannot be represented")))
279+
} else {
280+
err!(Intrinsic(format!("exact_div: {:?} cannot be divided by {:?} without remainder", *a, *b)))
281+
};
276282
}
277283
this.binop_ignore_overflow(mir::BinOp::Div, a, b, dest)?;
278284
},
@@ -459,6 +465,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
459465
)?;
460466
}
461467

468+
"unchecked_add" | "unchecked_sub" | "unchecked_mul" => {
469+
let l = this.read_immediate(args[0])?;
470+
let r = this.read_immediate(args[1])?;
471+
let op = match intrinsic_name.get() {
472+
"unchecked_add" => mir::BinOp::Add,
473+
"unchecked_sub" => mir::BinOp::Sub,
474+
"unchecked_mul" => mir::BinOp::Mul,
475+
_ => bug!(),
476+
};
477+
let (res, overflowed) = this.binary_op(op, l, r)?;
478+
if overflowed {
479+
return err!(Intrinsic(format!("Overflowing arithmetic in {}", intrinsic_name.get())));
480+
}
481+
this.write_scalar(res, dest)?;
482+
}
483+
462484
"uninit" => {
463485
// Check fast path: we don't want to force an allocation in case the destination is a simple value,
464486
// but we also do not want to create a new allocation with 0s and then copy that over.

src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub struct MiriConfig {
7272

7373
// Used by priroda.
7474
pub fn create_ecx<'mir, 'tcx: 'mir>(
75-
tcx: TyCtxt<'tcx, 'tcx>,
75+
tcx: TyCtxt<'tcx>,
7676
main_id: DefId,
7777
config: MiriConfig,
7878
) -> InterpResult<'tcx, InterpretCx<'mir, 'tcx, Evaluator<'tcx>>> {
@@ -212,7 +212,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
212212
}
213213

214214
pub fn eval_main<'tcx>(
215-
tcx: TyCtxt<'tcx, 'tcx>,
215+
tcx: TyCtxt<'tcx>,
216216
main_id: DefId,
217217
config: MiriConfig,
218218
) {
@@ -475,7 +475,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
475475

476476
fn find_foreign_static(
477477
def_id: DefId,
478-
tcx: TyCtxtAt<'tcx, 'tcx>,
478+
tcx: TyCtxtAt<'tcx>,
479479
) -> InterpResult<'tcx, Cow<'tcx, Allocation>> {
480480
let attrs = tcx.get_attrs(def_id);
481481
let link_name = match attr::first_attr_value_str_by_name(&attrs, sym::link_name) {

tests/compile-fail/div-by-zero-3.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(core_intrinsics)]
2+
3+
use std::intrinsics::*;
4+
5+
//error-pattern: Division by 0 in unchecked_rem
6+
7+
fn main() {
8+
unsafe {
9+
let _n = unchecked_rem(3u32, 0);
10+
}
11+
}

tests/compile-fail/exact_div1.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![feature(core_intrinsics)]
2+
fn main() {
3+
// divison by 0
4+
unsafe { std::intrinsics::exact_div(2, 0); } //~ ERROR divisor of zero
5+
}

tests/compile-fail/exact_div2.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![feature(core_intrinsics)]
2+
fn main() {
3+
// divison with a remainder
4+
unsafe { std::intrinsics::exact_div(2u16, 3); } //~ ERROR Scalar(0x0002) cannot be divided by Scalar(0x0003) without remainder
5+
}

tests/compile-fail/exact_div3.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![feature(core_intrinsics)]
2+
fn main() {
3+
// signed divison with a remainder
4+
unsafe { std::intrinsics::exact_div(-19i8, 2); } //~ ERROR Scalar(0xed) cannot be divided by Scalar(0x02) without remainder
5+
}

tests/compile-fail/exact_div4.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![feature(core_intrinsics)]
2+
fn main() {
3+
// divison of min_value by -1
4+
unsafe { std::intrinsics::exact_div(i64::min_value(), -1); } //~ ERROR result of dividing MIN by -1 cannot be represented
5+
}

0 commit comments

Comments
 (0)