diff --git a/src/comp/middle/check_const.rs b/src/comp/middle/check_const.rs index 44f3891c13c..81d41b06e49 100644 --- a/src/comp/middle/check_const.rs +++ b/src/comp/middle/check_const.rs @@ -1,5 +1,5 @@ import syntax::ast::*; -import syntax::visit; +import syntax::{visit, ast_util}; import driver::session::session; fn check_crate(sess: session, crate: @crate) { @@ -56,6 +56,23 @@ fn check_expr(sess: session, e: @expr, &&is_const: bool, v: visit::vt) { } } } + alt e.node { + expr_lit(@{node: lit_int(v, t), _}) { + if t != ty_char { + if (v as u64) > ast_util::int_ty_max( + t == ty_i ? sess.get_targ_cfg().int_type : t) { + sess.span_err(e.span, "literal out of range for its type"); + } + } + } + expr_lit(@{node: lit_uint(v, t), _}) { + if v > ast_util::uint_ty_max( + t == ty_u ? sess.get_targ_cfg().uint_type : t) { + sess.span_err(e.span, "literal out of range for its type"); + } + } + _ {} + } visit::visit_expr(e, is_const, v); } diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs index f6d019c2a85..dc1d0e0bbbb 100644 --- a/src/comp/syntax/ast_util.rs +++ b/src/comp/syntax/ast_util.rs @@ -132,6 +132,15 @@ fn int_ty_to_str(t: int_ty) -> str { } } +fn int_ty_max(t: int_ty) -> u64 { + alt t { + ty_i8. { 0x80u64 } + ty_i16. { 0x800u64 } + ty_char. | ty_i32. { 0x80000000u64 } + ty_i64. { 0x8000000000000000u64 } + } +} + fn uint_ty_to_str(t: uint_ty) -> str { alt t { ty_u. { "" } ty_u8. { "u8" } ty_u16. { "u16" } @@ -139,6 +148,15 @@ fn uint_ty_to_str(t: uint_ty) -> str { } } +fn uint_ty_max(t: uint_ty) -> u64 { + alt t { + ty_u8. { 0xffu64 } + ty_u16. { 0xffffu64 } + ty_u32. { 0xffffffffu64 } + ty_u64. { 0xffffffffffffffffu64 } + } +} + fn float_ty_to_str(t: float_ty) -> str { alt t { ty_f. { "" } ty_f32. { "f32" } ty_f64. { "f64" } } } diff --git a/src/libstd/u32.rs b/src/libstd/u32.rs index be6f649a979..f33b8414a4d 100644 --- a/src/libstd/u32.rs +++ b/src/libstd/u32.rs @@ -14,7 +14,7 @@ Const: max_value Return the maximal value for a u32 */ -const max_value: u32 = 4294967296u32; +const max_value: u32 = 0xffff_ffffu32; // // Local Variables: diff --git a/src/test/compile-fail/oversized-literal.rs b/src/test/compile-fail/oversized-literal.rs new file mode 100644 index 00000000000..30b61811b04 --- /dev/null +++ b/src/test/compile-fail/oversized-literal.rs @@ -0,0 +1,3 @@ +// error-pattern:literal out of range + +fn main() { log 300u8; }