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
Show file tree
Hide file tree
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
Expand Up @@ -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)
}

Expand Down
35 changes: 21 additions & 14 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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");
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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!()
Expand All @@ -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!()
Expand Down
11 changes: 7 additions & 4 deletions src/librustc/middle/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 7 additions & 3 deletions src/librustc/middle/trans/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Expand Down
2 changes: 0 additions & 2 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
38 changes: 35 additions & 3 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/ext/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
11 changes: 6 additions & 5 deletions src/libsyntax/ext/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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));
}
Expand Down
9 changes: 6 additions & 3 deletions src/libsyntax/ext/concat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
9 changes: 5 additions & 4 deletions src/libsyntax/ext/quote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
}
);
Expand Down
Loading