]> git.lizzy.rs Git - rust.git/commitdiff
Add range lint for float literals, fixing #10934
authorFalco Hirschenberger <falco.hirschenberger@gmail.com>
Wed, 9 Jul 2014 07:45:32 +0000 (09:45 +0200)
committerFalco Hirschenberger <falco.hirschenberger@gmail.com>
Thu, 10 Jul 2014 07:38:15 +0000 (09:38 +0200)
src/libcore/num/f32.rs
src/libcore/num/f64.rs
src/librustc/lint/builtin.rs
src/test/compile-fail/lint-type-overflow.rs

index cadc874891d2042109c0316e3db1a65439a1941f..82745663e0cad3bd8711493bc88af8065e0e7ae7 100644 (file)
@@ -11,6 +11,8 @@
 //! Operations and constants for 32-bits floats (`f32` type)
 
 #![doc(primitive = "f32")]
+// FIXME: MIN_VALUE and MAX_VALUE literals are parsed as -inf and inf #14353
+#![allow(type_overflow)]
 
 use intrinsics;
 use mem;
index 5e19015dd02819209f3d69f1f932dc6cc932e582..a3a82aeec5ec78f1cb8cbf453a8435ee874f15fc 100644 (file)
@@ -11,6 +11,8 @@
 //! Operations and constants for 64-bits floats (`f64` type)
 
 #![doc(primitive = "f64")]
+// FIXME: MIN_VALUE and MAX_VALUE literals are parsed as -inf and inf #14353
+#![allow(type_overflow)]
 
 use intrinsics;
 use mem;
index 481187f7c2ce74b499592b24d761a729de28186b..0f799e26cc7414bca4545549ccf3471ebb29136c 100644 (file)
 
 use std::cmp;
 use std::collections::HashMap;
-use std::i16;
-use std::i32;
-use std::i64;
-use std::i8;
-use std::u16;
-use std::u32;
-use std::u64;
-use std::u8;
+use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
 use std::gc::Gc;
 use syntax::abi;
 use syntax::ast_map;
@@ -214,7 +207,21 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
                                          "literal out of range for its type");
                         }
                     },
-
+                    ty::ty_float(t) => {
+                        let (min, max) = float_ty_range(t);
+                        let lit_val: f64 = match lit.node {
+                            ast::LitFloat(ref v, _) |
+                            ast::LitFloatUnsuffixed(ref v) => match from_str(v.get()) {
+                                Some(f) => f,
+                                None => return
+                            },
+                            _ => fail!()
+                        };
+                        if lit_val < min || lit_val > max {
+                            cx.span_lint(TYPE_OVERFLOW, e.span,
+                                         "literal out of range for its type");
+                        }
+                    },
                     _ => ()
                 };
             },
@@ -265,6 +272,13 @@ fn uint_ty_range(uint_ty: ast::UintTy) -> (u64, u64) {
             }
         }
 
+        fn float_ty_range(float_ty: ast::FloatTy) -> (f64, f64) {
+            match float_ty {
+                ast::TyF32  => (f32::MIN_VALUE as f64, f32::MAX_VALUE as f64),
+                ast::TyF64  => (f64::MIN_VALUE,        f64::MAX_VALUE)
+            }
+        }
+
         fn check_limits(tcx: &ty::ctxt, binop: ast::BinOp,
                         l: &ast::Expr, r: &ast::Expr) -> bool {
             let (lit, expr, swap) = match (&l.node, &r.node) {
index e5a5c7dd1c7c26a589bc9cc82ed2b68cfbfb7f1e..676a6e7cb4452f5e2843c207a339084095626336 100644 (file)
@@ -47,4 +47,9 @@ fn main() {
     let x = -2147483648_i32; // should be OK
     let x: i32 = -2147483649; //~ error: literal out of range for its type
     let x = -2147483649_i32; //~ error: literal out of range for its type
+
+    let x = -3.40282348e+38_f32; //~ error: literal out of range for its type
+    let x =  3.40282348e+38_f32; //~ error: literal out of range for its type
+    let x = -1.7976931348623159e+308_f64; //~ error: literal out of range for its type
+    let x =  1.7976931348623159e+308_f64; //~ error: literal out of range for its type
 }