Skip to content

Fixes missing overflow lint for i64 #15709

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 5, 2014
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libfourcc/lib.rs
Original file line number Diff line number Diff line change
@@ -124,7 +124,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
(val << 8) | (byte as u32)
};
}
let e = cx.expr_lit(sp, ast::LitUint(val as u64, ast::TyU32));
let e = cx.expr_lit(sp, ast::LitInt(val as u64, ast::UnsignedIntLit(ast::TyU32)));
MacExpr::new(e)
}

35 changes: 21 additions & 14 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
@@ -135,7 +135,7 @@ impl LintPass for TypeLimits {
match expr.node {
ast::ExprLit(lit) => {
match lit.node {
ast::LitUint(..) => {
ast::LitInt(_, ast::UnsignedIntLit(_)) => {
cx.span_lint(UNSIGNED_NEGATE, e.span,
"negation of unsigned int literal may \
be unintentional");
@@ -177,15 +177,25 @@ impl LintPass for TypeLimits {
} else { t };
let (min, max) = int_ty_range(int_type);
let mut lit_val: i64 = match lit.node {
ast::LitInt(v, _) => v,
ast::LitUint(v, _) => v as i64,
ast::LitIntUnsuffixed(v) => v,
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
if v > i64::MAX 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 {
if lit_val < min || lit_val > max {
cx.span_lint(TYPE_OVERFLOW, e.span,
"literal out of range for its type");
}
@@ -197,9 +207,7 @@ impl LintPass for TypeLimits {
let (min, max) = uint_ty_range(uint_type);
let lit_val: u64 = match lit.node {
ast::LitByte(_v) => return, // _v is u8, within range by definition
ast::LitInt(v, _) => v as u64,
ast::LitUint(v, _) => v,
ast::LitIntUnsuffixed(v) => v as u64,
ast::LitInt(v, _) => v,
_ => fail!()
};
if lit_val < min || lit_val > max {
@@ -294,9 +302,10 @@ impl LintPass for TypeLimits {
let (min, max) = int_ty_range(int_ty);
let lit_val: i64 = match lit.node {
ast::ExprLit(li) => match li.node {
ast::LitInt(v, _) => v,
ast::LitUint(v, _) => v as i64,
ast::LitIntUnsuffixed(v) => v,
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => v as i64,
ast::LitInt(v, ast::SignedIntLit(_, ast::Minus)) |
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Minus)) => -(v as i64),
_ => return true
},
_ => fail!()
@@ -307,9 +316,7 @@ impl LintPass for TypeLimits {
let (min, max): (u64, u64) = uint_ty_range(uint_ty);
let lit_val: u64 = match lit.node {
ast::ExprLit(li) => match li.node {
ast::LitInt(v, _) => v as u64,
ast::LitUint(v, _) => v,
ast::LitIntUnsuffixed(v) => v as u64,
ast::LitInt(v, _) => v,
_ => return true
},
_ => fail!()
11 changes: 7 additions & 4 deletions src/librustc/middle/const_eval.rs
Original file line number Diff line number Diff line change
@@ -560,10 +560,13 @@ pub fn lit_to_const(lit: &Lit) -> const_val {
}
LitByte(n) => const_uint(n as u64),
LitChar(n) => const_uint(n as u64),
LitInt(n, _) => const_int(n),
LitUint(n, _) => const_uint(n),
LitIntUnsuffixed(n) => const_int(n),
LitFloat(ref n, _) | LitFloatUnsuffixed(ref n) => {
LitInt(n, ast::SignedIntLit(_, ast::Plus)) |
LitInt(n, ast::UnsuffixedIntLit(ast::Plus)) => const_int(n as i64),
LitInt(n, ast::SignedIntLit(_, ast::Minus)) |
LitInt(n, ast::UnsuffixedIntLit(ast::Minus)) => const_int(-(n as i64)),
LitInt(n, ast::UnsignedIntLit(_)) => const_uint(n),
LitFloat(ref n, _) |
LitFloatUnsuffixed(ref n) => {
const_float(from_str::<f64>(n.get()).unwrap() as f64)
}
LitNil => const_nil,
10 changes: 7 additions & 3 deletions src/librustc/middle/trans/consts.rs
Original file line number Diff line number Diff line change
@@ -47,9 +47,13 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit)
match lit.node {
ast::LitByte(b) => C_integral(Type::uint_from_ty(cx, ast::TyU8), b as u64, false),
ast::LitChar(i) => C_integral(Type::char(cx), i as u64, false),
ast::LitInt(i, t) => C_integral(Type::int_from_ty(cx, t), i as u64, true),
ast::LitUint(u, t) => C_integral(Type::uint_from_ty(cx, t), u, false),
ast::LitIntUnsuffixed(i) => {
ast::LitInt(i, ast::SignedIntLit(t, _)) => {
C_integral(Type::int_from_ty(cx, t), i, true)
}
ast::LitInt(u, ast::UnsignedIntLit(t)) => {
C_integral(Type::uint_from_ty(cx, t), u, false)
}
ast::LitInt(i, ast::UnsuffixedIntLit(_)) => {
let lit_int_ty = ty::node_id_to_type(cx.tcx(), e.id);
match ty::get(lit_int_ty).sty {
ty::ty_int(t) => {
6 changes: 3 additions & 3 deletions src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
@@ -2057,9 +2057,9 @@ fn check_lit(fcx: &FnCtxt,
}
ast::LitByte(_) => ty::mk_u8(),
ast::LitChar(_) => ty::mk_char(),
ast::LitInt(_, t) => ty::mk_mach_int(t),
ast::LitUint(_, t) => ty::mk_mach_uint(t),
ast::LitIntUnsuffixed(_) => {
ast::LitInt(_, ast::SignedIntLit(t, _)) => ty::mk_mach_int(t),
ast::LitInt(_, ast::UnsignedIntLit(t)) => ty::mk_mach_uint(t),
ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
let opt_ty = expected.map_to_option(fcx, |sty| {
match *sty {
ty::ty_int(i) => Some(ty::mk_mach_int(i)),
2 changes: 0 additions & 2 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
@@ -1947,8 +1947,6 @@ fn lit_to_string(lit: &ast::Lit) -> String {
},
ast::LitChar(c) => format!("'{}'", c),
ast::LitInt(i, _t) => i.to_string(),
ast::LitUint(u, _t) => u.to_string(),
ast::LitIntUnsuffixed(i) => i.to_string(),
ast::LitFloat(ref f, _t) => f.get().to_string(),
ast::LitFloatUnsuffixed(ref f) => f.get().to_string(),
ast::LitBool(b) => b.to_string(),
38 changes: 35 additions & 3 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ use parse::token::{InternedString, str_to_ident};
use parse::token;

use std::fmt;
use std::num::Zero;
use std::fmt::Show;
use std::option::Option;
use std::rc::Rc;
@@ -656,15 +657,46 @@ pub enum StrStyle {

pub type Lit = Spanned<Lit_>;

#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum Sign {
Minus,
Plus
}

impl<T: PartialOrd+Zero> Sign {
pub fn new(n: T) -> Sign {
if n < Zero::zero() {
Minus
} else {
Plus
}
}
}

#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum LitIntType {
SignedIntLit(IntTy, Sign),
UnsignedIntLit(UintTy),
UnsuffixedIntLit(Sign)
}

impl LitIntType {
pub fn suffix_len(&self) -> uint {
match *self {
UnsuffixedIntLit(_) => 0,
SignedIntLit(s, _) => s.suffix_len(),
UnsignedIntLit(u) => u.suffix_len()
}
}
}

#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum Lit_ {
LitStr(InternedString, StrStyle),
LitBinary(Rc<Vec<u8> >),
LitByte(u8),
LitChar(char),
LitInt(i64, IntTy),
LitUint(u64, UintTy),
LitIntUnsuffixed(i64),
LitInt(u64, LitIntType),
LitFloat(InternedString, FloatTy),
LitFloatUnsuffixed(InternedString),
LitNil,
6 changes: 3 additions & 3 deletions src/libsyntax/ext/build.rs
Original file line number Diff line number Diff line change
@@ -626,13 +626,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr(sp, ast::ExprLit(box(GC) respan(sp, lit)))
}
fn expr_uint(&self, span: Span, i: uint) -> Gc<ast::Expr> {
self.expr_lit(span, ast::LitUint(i as u64, ast::TyU))
self.expr_lit(span, ast::LitInt(i as u64, ast::UnsignedIntLit(ast::TyU)))
}
fn expr_int(&self, sp: Span, i: int) -> Gc<ast::Expr> {
self.expr_lit(sp, ast::LitInt(i as i64, ast::TyI))
self.expr_lit(sp, ast::LitInt(i as u64, ast::SignedIntLit(ast::TyI, ast::Sign::new(i))))
}
fn expr_u8(&self, sp: Span, u: u8) -> Gc<ast::Expr> {
self.expr_lit(sp, ast::LitUint(u as u64, ast::TyU8))
self.expr_lit(sp, ast::LitInt(u as u64, ast::UnsignedIntLit(ast::TyU8)))
}
fn expr_bool(&self, sp: Span, value: bool) -> Gc<ast::Expr> {
self.expr_lit(sp, ast::LitBool(value))
11 changes: 6 additions & 5 deletions src/libsyntax/ext/bytes.rs
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
}

// u8 literal, push to vector expression
ast::LitUint(v, ast::TyU8) => {
ast::LitInt(v, ast::UnsignedIntLit(ast::TyU8)) => {
if v > 0xFF {
cx.span_err(expr.span, "too large u8 literal in bytes!");
err = true;
@@ -57,13 +57,14 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
}

// integer literal, push to vector expression
ast::LitIntUnsuffixed(v) => {
ast::LitInt(_, ast::UnsuffixedIntLit(ast::Minus)) => {
cx.span_err(expr.span, "negative integer literal in bytes!");
err = true;
}
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
if v > 0xFF {
cx.span_err(expr.span, "too large integer literal in bytes!");
err = true;
} else if v < 0 {
cx.span_err(expr.span, "negative integer literal in bytes!");
err = true;
} else {
bytes.push(cx.expr_u8(expr.span, v as u8));
}
9 changes: 6 additions & 3 deletions src/libsyntax/ext/concat.rs
Original file line number Diff line number Diff line change
@@ -37,11 +37,14 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
ast::LitChar(c) => {
accumulator.push_char(c);
}
ast::LitInt(i, _) | ast::LitIntUnsuffixed(i) => {
ast::LitInt(i, ast::UnsignedIntLit(_)) |
ast::LitInt(i, ast::SignedIntLit(_, ast::Plus)) |
ast::LitInt(i, ast::UnsuffixedIntLit(ast::Plus)) => {
accumulator.push_str(format!("{}", i).as_slice());
}
ast::LitUint(u, _) => {
accumulator.push_str(format!("{}", u).as_slice());
ast::LitInt(i, ast::SignedIntLit(_, ast::Minus)) |
ast::LitInt(i, ast::UnsuffixedIntLit(ast::Minus)) => {
accumulator.push_str(format!("-{}", i).as_slice());
}
ast::LitNil => {}
ast::LitBool(b) => {
2 changes: 1 addition & 1 deletion src/libsyntax/ext/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
@@ -996,7 +996,7 @@ impl<'a> MethodDef<'a> {
let arms : Vec<ast::Arm> = variants.iter().enumerate()
.map(|(index, &variant)| {
let pat = variant_to_pat(cx, sp, &*variant);
let lit = ast::LitUint(index as u64, ast::TyU);
let lit = ast::LitInt(index as u64, ast::UnsignedIntLit(ast::TyU));
cx.arm(sp, vec![pat], cx.expr_lit(sp, lit))
}).collect();

9 changes: 5 additions & 4 deletions src/libsyntax/ext/quote.rs
Original file line number Diff line number Diff line change
@@ -189,16 +189,17 @@ pub mod rt {
(signed, $t:ty, $tag:ident) => (
impl ToSource for $t {
fn to_source(&self) -> String {
let lit = dummy_spanned(ast::LitInt(*self as i64, ast::$tag));
pprust::lit_to_string(&lit)
let lit = ast::LitInt(*self as u64, ast::SignedIntLit(ast::$tag,
ast::Sign::new(*self)));
pprust::lit_to_string(&dummy_spanned(lit))
}
}
);
(unsigned, $t:ty, $tag:ident) => (
impl ToSource for $t {
fn to_source(&self) -> String {
let lit = dummy_spanned(ast::LitUint(*self as u64, ast::$tag));
pprust::lit_to_string(&lit)
let lit = ast::LitInt(*self as u64, ast::UnsignedIntLit(ast::$tag));
pprust::lit_to_string(&dummy_spanned(lit))
}
}
);
Loading