Skip to content

Commit d060e20

Browse files
committed
[WIP] Make usize overflow always have debug-assertions semantics
This is a prototype for rust-lang/rfcs#2635 to enable us to collect some measurements.
1 parent 74e35d2 commit d060e20

File tree

6 files changed

+19
-11
lines changed

6 files changed

+19
-11
lines changed

src/librustc_codegen_llvm/context.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ use type_of::PointeeInfo;
1212
use rustc_codegen_ssa::traits::*;
1313
use libc::c_uint;
1414

15+
use syntax::ast;
16+
1517
use rustc_data_structures::base_n;
1618
use rustc_data_structures::small_c_str::SmallCStr;
1719
use rustc::mir::mono::Stats;
1820
use rustc::session::config::{self, DebugInfo};
1921
use rustc::session::Session;
2022
use rustc::ty::layout::{LayoutError, LayoutOf, Size, TyLayout, VariantIdx};
21-
use rustc::ty::{self, Ty, TyCtxt};
23+
use rustc::ty::{self, Ty, TyCtxt, TyKind};
2224
use rustc::util::nodemap::FxHashMap;
2325
use rustc_target::spec::{HasTargetSpec, Target};
2426
use rustc_codegen_ssa::callee::resolve_and_get_fn;
@@ -409,8 +411,14 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
409411
&self.tcx.sess
410412
}
411413

412-
fn check_overflow(&self) -> bool {
413-
self.check_overflow
414+
fn check_overflow(&self, ty: Option<Ty<'tcx>>) -> bool {
415+
let type_specific_overflow = match ty {
416+
Some(ty) => {
417+
ty.sty == TyKind::Uint(ast::UintTy::Usize)
418+
},
419+
None => false
420+
};
421+
self.check_overflow || type_specific_overflow
414422
}
415423

416424
fn stats(&self) -> &RefCell<Stats> {

src/librustc_codegen_ssa/mir/block.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
339339
// NOTE: Unlike binops, negation doesn't have its own
340340
// checked operation, just a comparison with the minimum
341341
// value, so we have to check for the assert message.
342-
if !bx.check_overflow() {
342+
if !bx.check_overflow(None) {
343343
if let mir::interpret::EvalErrorKind::OverflowNeg = *msg {
344344
const_cond = Some(expected);
345345
}

src/librustc_codegen_ssa/mir/rvalue.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
670670
// with #[rustc_inherit_overflow_checks] and inlined from
671671
// another crate (mostly core::num generic/#[inline] fns),
672672
// while the current crate doesn't use overflow checks.
673-
if !bx.cx().check_overflow() {
673+
if !bx.cx().check_overflow(Some(input_ty)) {
674674
let val = self.codegen_scalar_binop(bx, op, lhs, rhs, input_ty);
675675
return OperandValue::Pair(val, bx.cx().const_bool(false));
676676
}

src/librustc_codegen_ssa/traits/misc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub trait MiscMethods<'tcx>: BackendTypes {
1212
fn vtables(
1313
&self,
1414
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Self::Value>>;
15-
fn check_overflow(&self) -> bool;
15+
fn check_overflow(&self, ty: Option<Ty<'tcx>>) -> bool;
1616
fn instances(&self) -> &RefCell<FxHashMap<Instance<'tcx>, Self::Value>>;
1717
fn get_fn(&self, instance: Instance<'tcx>) -> Self::Value;
1818
fn get_param(&self, llfn: Self::Value, index: c_uint) -> Self::Value;

src/librustc_mir/build/expr/as_rvalue.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
8484
ExprKind::Unary { op, arg } => {
8585
let arg = unpack!(block = this.as_operand(block, scope, arg));
8686
// Check for -MIN on signed integers
87-
if this.hir.check_overflow() && op == UnOp::Neg && expr.ty.is_signed() {
87+
if this.hir.check_overflow(expr.ty) && op == UnOp::Neg && expr.ty.is_signed() {
8888
let bool_ty = this.hir.bool_ty();
8989

9090
let minval = this.minval_literal(expr_span, expr.ty);
@@ -410,7 +410,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
410410
) -> BlockAnd<Rvalue<'tcx>> {
411411
let source_info = self.source_info(span);
412412
let bool_ty = self.hir.bool_ty();
413-
if self.hir.check_overflow() && op.is_checkable() && ty.is_integral() {
413+
if self.hir.check_overflow(ty) && op.is_checkable() && ty.is_integral() {
414414
let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty]);
415415
let result_value = self.temp(result_tup, span);
416416

src/librustc_mir/hair/cx/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc::hir::Node;
1111
use rustc::middle::region;
1212
use rustc::infer::InferCtxt;
1313
use rustc::ty::subst::Subst;
14-
use rustc::ty::{self, Ty, TyCtxt};
14+
use rustc::ty::{self, Ty, TyCtxt, TyKind};
1515
use rustc::ty::subst::{Kind, Substs};
1616
use rustc::ty::layout::VariantIdx;
1717
use syntax::ast;
@@ -218,8 +218,8 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
218218
self.tables
219219
}
220220

221-
pub fn check_overflow(&self) -> bool {
222-
self.check_overflow
221+
pub fn check_overflow(&self, ty: Ty<'tcx>) -> bool {
222+
self.check_overflow || ty.sty == TyKind::Uint(ast::UintTy::Usize)
223223
}
224224

225225
pub fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>, span: Span) -> bool {

0 commit comments

Comments
 (0)