Add unchecked_shl/shr checks for intrinsics

This commit is contained in:
Tim 2018-09-06 13:13:07 +02:00
parent 20ca02569a
commit 58af73c370
3 changed files with 69 additions and 4 deletions

View File

@ -105,8 +105,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
| "overflowing_add"
| "overflowing_sub"
| "overflowing_mul"
| "unchecked_shl"
| "unchecked_shr"
| "add_with_overflow"
| "sub_with_overflow"
| "mul_with_overflow" => {
@ -116,8 +114,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
"overflowing_add" => (BinOp::Add, true),
"overflowing_sub" => (BinOp::Sub, true),
"overflowing_mul" => (BinOp::Mul, true),
"unchecked_shl" => (BinOp::Shl, true),
"unchecked_shr" => (BinOp::Shr, true),
"add_with_overflow" => (BinOp::Add, false),
"sub_with_overflow" => (BinOp::Sub, false),
"mul_with_overflow" => (BinOp::Mul, false),
@ -129,6 +125,34 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
self.binop_with_overflow(bin_op, lhs, rhs, dest)?;
}
}
"unchecked_shl" | "unchecked_shr" => {
let bits = dest.layout.size.bytes() as u128 * 8;
let l = self.read_value(args[0])?;
let r = self.read_value(args[1])?;
let r_ty = substs.type_at(0);
let r_layout_of = self.layout_of(r_ty)?;
let r_val = r.to_scalar()?.to_bits(r_layout_of.size)?;
let bin_op = match intrinsic_name {
"unchecked_shl" => {
if r_val >= bits {
return err!(Intrinsic(
format!("Overflowing shift by {} in unchecked_shl", r_val),
));
}
BinOp::Shl
},
"unchecked_shr" => {
if r_val >= bits {
return err!(Intrinsic(
format!("Overflowing shift by {} in unchecked_shr", r_val),
));
}
BinOp::Shr
},
_ => bug!("Already checked for int ops")
};
self.binop_ignore_overflow(bin_op, l, r, dest)?;
}
"transmute" => {
// Go through an allocation, to make sure the completely different layouts
// do not pose a problem. (When the user transmutes through a union,

View File

@ -0,0 +1,21 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(core_intrinsics)]
use std::intrinsics;
const SHR: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) };
//^~ ERROR: Overflowing shift by 8 in unchecked_shr
const SHL: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) };
//^~ ERROR: Overflowing shift by 8 in unchecked_shl
fn main() {
}

View File

@ -0,0 +1,20 @@
error: this constant cannot be used
--> $DIR/const-int-unchecked.rs:15:1
|
LL | const SHR: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^
| |
| Overflowing shift by 8 in unchecked_shr
|
= note: #[deny(const_err)] on by default
error: this constant cannot be used
--> $DIR/const-int-unchecked.rs:17:1
|
LL | const SHL: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^
| |
| Overflowing shift by 8 in unchecked_shl
error: aborting due to 2 previous errors