about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorFalco Hirschenberger <falco.hirschenberger@gmail.com>2014-08-05 09:59:03 +0200
committerFalco Hirschenberger <falco.hirschenberger@gmail.com>2014-08-05 09:59:03 +0200
commit0dc215741b34236c310e409c437600ba0165c97c (patch)
treebfaee6d4c3d1b082fadf859cb106b5e99d458028 /src/libsyntax/parse
parent795f6ae829ab1bfd72394a5da9096e2717ec0f62 (diff)
downloadrust-0dc215741b34236c310e409c437600ba0165c97c.tar.gz
rust-0dc215741b34236c310e409c437600ba0165c97c.zip
Fixes missing overflow lint for i64 #14269
The `type_overflow` lint, doesn't catch the overflow for `i64` because
the overflow happens earlier in the parse phase when the `u64` as biggest
possible int gets casted to `i64` , without checking the for overflows.
We can't lint in the parse phase, so a refactoring of the `LitInt` type
was necessary.

The types `LitInt`, `LitUint` and `LitIntUnsuffixed` where merged to one
type `LitInt` which stores it's value as `u64`. An additional parameter was
added which indicate the signedness of the type and the sign of the value.
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/mod.rs57
-rw-r--r--src/libsyntax/parse/parser.rs4
2 files changed, 22 insertions, 39 deletions
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index a3e169cd511..8f960e37de2 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -515,31 +515,13 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
     debug!("parse_integer_lit: {}", s);
 
     if s.len() == 1 {
-        return ast::LitIntUnsuffixed((s.char_at(0)).to_digit(10).unwrap() as i64);
+        let n = (s.char_at(0)).to_digit(10).unwrap();
+        return ast::LitInt(n as u64, ast::UnsuffixedIntLit(ast::Sign::new(n)));
     }
 
     let mut base = 10;
     let orig = s;
-
-    #[deriving(Show)]
-    enum Result {
-        Nothing,
-        Signed(ast::IntTy),
-        Unsigned(ast::UintTy)
-    }
-
-    impl Result {
-        fn suffix_len(&self) -> uint {
-            match *self {
-                Nothing => 0,
-                Signed(s) => s.suffix_len(),
-                Unsigned(u) => u.suffix_len()
-            }
-        }
-    }
-
-    let mut ty = Nothing;
-
+    let mut ty = ast::UnsuffixedIntLit(ast::Plus);
 
     if s.char_at(0) == '0' {
         match s.char_at(1) {
@@ -556,13 +538,13 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
 
     let last = s.len() - 1;
     match s.char_at(last) {
-        'i' => ty = Signed(ast::TyI),
-        'u' => ty = Unsigned(ast::TyU),
+        'i' => ty = ast::SignedIntLit(ast::TyI, ast::Plus),
+        'u' => ty = ast::UnsignedIntLit(ast::TyU),
         '8' => {
             if s.len() > 2 {
                 match s.char_at(last - 1) {
-                    'i' => ty = Signed(ast::TyI8),
-                    'u' => ty = Unsigned(ast::TyU8),
+                    'i' => ty = ast::SignedIntLit(ast::TyI8, ast::Plus),
+                    'u' => ty = ast::UnsignedIntLit(ast::TyU8),
                     _ => { }
                 }
             }
@@ -570,8 +552,8 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
         '6' => {
             if s.len() > 3 && s.char_at(last - 1) == '1' {
                 match s.char_at(last - 2) {
-                    'i' => ty = Signed(ast::TyI16),
-                    'u' => ty = Unsigned(ast::TyU16),
+                    'i' => ty = ast::SignedIntLit(ast::TyI16, ast::Plus),
+                    'u' => ty = ast::UnsignedIntLit(ast::TyU16),
                     _ => { }
                 }
             }
@@ -579,8 +561,8 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
         '2' => {
             if s.len() > 3 && s.char_at(last - 1) == '3' {
                 match s.char_at(last - 2) {
-                    'i' => ty = Signed(ast::TyI32),
-                    'u' => ty = Unsigned(ast::TyU32),
+                    'i' => ty = ast::SignedIntLit(ast::TyI32, ast::Plus),
+                    'u' => ty = ast::UnsignedIntLit(ast::TyU32),
                     _ => { }
                 }
             }
@@ -588,8 +570,8 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
         '4' => {
             if s.len() > 3 && s.char_at(last - 1) == '6' {
                 match s.char_at(last - 2) {
-                    'i' => ty = Signed(ast::TyI64),
-                    'u' => ty = Unsigned(ast::TyU64),
+                    'i' => ty = ast::SignedIntLit(ast::TyI64, ast::Plus),
+                    'u' => ty = ast::UnsignedIntLit(ast::TyU64),
                     _ => { }
                 }
             }
@@ -597,21 +579,22 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
         _ => { }
     }
 
-
-    s = s.slice_to(s.len() - ty.suffix_len());
-
     debug!("The suffix is {}, base {}, the new string is {}, the original \
            string was {}", ty, base, s, orig);
 
+    s = s.slice_to(s.len() - ty.suffix_len());
+
     let res: u64 = match ::std::num::from_str_radix(s, base) {
         Some(r) => r,
         None => { sd.span_err(sp, "int literal is too large"); 0 }
     };
 
+    // adjust the sign
+    let sign = ast::Sign::new(res);
     match ty {
-        Nothing => ast::LitIntUnsuffixed(res as i64),
-        Signed(t) => ast::LitInt(res as i64, t),
-        Unsigned(t) => ast::LitUint(res, t)
+        ast::SignedIntLit(t, _) => ast::LitInt(res, ast::SignedIntLit(t, sign)),
+        ast::UnsuffixedIntLit(_) => ast::LitInt(res, ast::UnsuffixedIntLit(sign)),
+        us@ast::UnsignedIntLit(_) => ast::LitInt(res, us)
     }
 }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index de3be4f8f38..18b1d60d4e9 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -34,7 +34,7 @@ use ast::{Ident, NormalFn, Inherited, Item, Item_, ItemStatic};
 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl};
 use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, Lit, Lit_};
 use ast::{LitBool, LitChar, LitByte, LitBinary};
-use ast::{LitNil, LitStr, LitUint, Local, LocalLet};
+use ast::{LitNil, LitStr, LitInt, Local, LocalLet};
 use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal};
 use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability};
 use ast::{NamedField, UnNeg, NoReturn, UnNot, P, Pat, PatEnum};
@@ -1889,7 +1889,7 @@ impl<'a> Parser<'a> {
     pub fn mk_lit_u32(&mut self, i: u32) -> Gc<Expr> {
         let span = &self.span;
         let lv_lit = box(GC) codemap::Spanned {
-            node: LitUint(i as u64, TyU32),
+            node: LitInt(i as u64, ast::UnsignedIntLit(TyU32)),
             span: *span
         };