Fixes type range issue during linting (#16684)

- Ensures the propagated negation sign is properly utilized during type
   checking.
 - Removed redundant type checking, specifically regarding the out of bounds checking
   on a bounded type.
 - Closes #16684
This commit is contained in:
Robert Gawdzik ☢ 2014-08-26 03:42:58 -04:00 committed by Robert Gawdzik ☢
parent e024017f60
commit 5eea93af39
2 changed files with 10 additions and 18 deletions

View File

@ -172,33 +172,24 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
ast::ExprLit(lit) => {
match ty::get(ty::expr_ty(cx.tcx, e)).sty {
ty::ty_int(t) => {
match lit.node {
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
let int_type = if t == ast::TyI {
cx.sess().targ_cfg.int_type
} else { t };
let (min, max) = int_ty_range(int_type);
let mut lit_val: i64 = match lit.node {
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
if v > i64::MAX as u64{
let negative = self.negated_expr_id == e.id;
if (negative && v > (min.abs() as u64)) ||
(!negative && v > (max.abs() as u64)) {
cx.span_lint(TYPE_OVERFLOW, e.span,
"literal out of range for its type");
return;
}
v as i64
}
ast::LitInt(v, ast::SignedIntLit(_, ast::Minus)) |
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Minus)) => {
-(v as i64)
}
_ => fail!()
};
if self.negated_expr_id == e.id {
lit_val *= -1;
}
if lit_val < min || lit_val > max {
cx.span_lint(TYPE_OVERFLOW, e.span,
"literal out of range for its type");
}
},
ty::ty_uint(t) => {
let uint_type = if t == ast::TyU {

View File

@ -49,6 +49,7 @@ fn main() {
let x = -2147483649_i32; //~ error: literal out of range for its type
let x = 9223372036854775808_i64; //~ error: literal out of range for its type
let x = -9223372036854775808_i64; // should be OK
let x = 18446744073709551615_i64; //~ error: literal out of range for its type
let x = -3.40282348e+38_f32; //~ error: literal out of range for its type