From 5bcd0a0b5030487613bee37ed38945e42c4e6b85 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Wed, 15 Oct 2014 20:26:43 +0300 Subject: [PATCH] prevent the creation of integers too big for the target architecture --- src/librustc/middle/trans/adt.rs | 4 ++-- src/librustc/middle/trans/common.rs | 23 ++++++++++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 66d4b3d804a..861ed01aa3b 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -478,7 +478,7 @@ fn ensure_struct_fits_in_address_space(ccx: &CrateContext, offset += machine::llsize_of_alloc(ccx, llty); // We can get away with checking for overflow once per iteration, - // because field sizes are less than 1<<60. + // because field sizes are less than 1<<61. if offset >= ccx.max_obj_size() { ccx.report_overbig_object(scapegoat); } @@ -498,7 +498,7 @@ fn ensure_enum_fits_in_address_space(ccx: &CrateContext, let discr_size = machine::llsize_of_alloc(ccx, ll_inttype(ccx, discr)); let (field_size, field_align) = union_size_and_align(fields); - // This can't overflow because field_size, discr_size, field_align < 1<<60 + // This can't overflow because field_size, discr_size, field_align < 1<<61 let total_size = roundup(discr_size, field_align) + field_size; if total_size >= ccx.max_obj_size() { diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index a4eb540174f..38a99f16ed6 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -596,17 +596,34 @@ pub fn C_u64(ccx: &CrateContext, i: u64) -> ValueRef { } pub fn C_int(ccx: &CrateContext, i: I) -> ValueRef { - C_integral(ccx.int_type(), i.as_i64() as u64, true) + let v = i.as_i64(); + + match machine::llbitsize_of_real(ccx.int_type()) { + 32 => assert!(v < (1<<31) && v >= -(1<<31)), + 64 => {}, + n => fail!("unsupported target size: {}", n) + } + + C_integral(ccx.int_type(), v as u64, true) } pub fn C_uint(ccx: &CrateContext, i: I) -> ValueRef { - C_integral(ccx.int_type(), i.as_u64(), false) + let v = i.as_u64(); + + match machine::llbitsize_of_real(ccx.int_type()) { + 32 => assert!(v < (1<<32)), + 64 => {}, + n => fail!("unsupported target size: {}", n) + } + + C_integral(ccx.int_type(), v, false) } pub trait AsI64 { fn as_i64(self) -> i64; } pub trait AsU64 { fn as_u64(self) -> u64; } -// FIXME: remove the intptr conversions +// FIXME: remove the intptr conversions, because they +// are host-architecture-dependent impl AsI64 for i64 { fn as_i64(self) -> i64 { self as i64 }} impl AsI64 for i32 { fn as_i64(self) -> i64 { self as i64 }} impl AsI64 for int { fn as_i64(self) -> i64 { self as i64 }}