]> git.lizzy.rs Git - rust.git/commitdiff
const_err lint all constant expressions
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Tue, 26 Apr 2016 09:18:48 +0000 (11:18 +0200)
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Tue, 26 Apr 2016 09:18:48 +0000 (11:18 +0200)
src/librustc_passes/consts.rs
src/test/compile-fail/const-err-early.rs
src/test/compile-fail/const-err.rs
src/test/compile-fail/lint-exceeding-bitshifts.rs
src/test/compile-fail/lint-type-overflow2.rs

index 2fa7f026a521aa900dd6a5dfddbb2f611304dfbc..32bcac40289eb466953c5b13950eaecb7bbcb168 100644 (file)
@@ -28,8 +28,8 @@
 use rustc::ty::cast::{CastKind};
 use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, compare_lit_exprs};
 use rustc_const_eval::{eval_const_expr_partial, lookup_const_by_id};
-use rustc_const_eval::ErrKind::{IndexOpFeatureGated, UnimplementedConstVal};
-use rustc_const_eval::ErrKind::ErroneousReferencedConstant;
+use rustc_const_eval::ErrKind::{IndexOpFeatureGated, UnimplementedConstVal, MiscCatchAll};
+use rustc_const_eval::ErrKind::{ErroneousReferencedConstant, MiscBinaryOp};
 use rustc_const_eval::EvalHint::ExprTypeChecked;
 use rustc::hir::def::Def;
 use rustc::hir::def_id::DefId;
@@ -437,29 +437,6 @@ fn visit_expr(&mut self, ex: &hir::Expr) {
                 }
                 intravisit::walk_expr(self, ex);
             }
-            // Division by zero and overflow checking.
-            hir::ExprBinary(op, _, _) => {
-                intravisit::walk_expr(self, ex);
-                let div_or_rem = op.node == hir::BiDiv || op.node == hir::BiRem;
-                match node_ty.sty {
-                    ty::TyUint(_) | ty::TyInt(_) if div_or_rem => {
-                        if !self.qualif.intersects(ConstQualif::NOT_CONST) {
-                            match eval_const_expr_partial(
-                                    self.tcx, ex, ExprTypeChecked, None) {
-                                Ok(_) => {}
-                                Err(ConstEvalErr { kind: UnimplementedConstVal(_), ..}) |
-                                Err(ConstEvalErr { kind: IndexOpFeatureGated, ..}) => {},
-                                Err(msg) => {
-                                    self.tcx.sess.add_lint(CONST_ERR, ex.id,
-                                                           msg.span,
-                                                           msg.description().into_owned())
-                                }
-                            }
-                        }
-                    }
-                    _ => {}
-                }
-            }
             _ => intravisit::walk_expr(self, ex)
         }
 
@@ -505,6 +482,24 @@ fn visit_expr(&mut self, ex: &hir::Expr) {
             }
             None => {}
         }
+
+        if self.mode == Mode::Var && !self.qualif.intersects(ConstQualif::NOT_CONST) {
+            match eval_const_expr_partial(self.tcx, ex, ExprTypeChecked, None) {
+                Ok(_) => {}
+                Err(ConstEvalErr { kind: UnimplementedConstVal(_), ..}) |
+                Err(ConstEvalErr { kind: MiscCatchAll, ..}) |
+                Err(ConstEvalErr { kind: MiscBinaryOp, ..}) |
+                Err(ConstEvalErr { kind: ErroneousReferencedConstant(_), ..}) |
+                Err(ConstEvalErr { kind: IndexOpFeatureGated, ..}) => {},
+                Err(msg) => {
+                    self.qualif = self.qualif | ConstQualif::NOT_CONST;
+                    self.tcx.sess.add_lint(CONST_ERR, ex.id,
+                                           msg.span,
+                                           msg.description().into_owned())
+                }
+            }
+        }
+
         self.tcx.const_qualif_map.borrow_mut().insert(ex.id, self.qualif);
         // Don't propagate certain flags.
         self.qualif = outer | (self.qualif - ConstQualif::HAS_STATIC_BORROWS);
index cdcdb919bdef57e2bafc84849e8dd0532f4606bc..7567791c24066040bef4596f7a2fd7213f077a35 100644 (file)
@@ -18,5 +18,5 @@
 pub const E: u8 = [5u8][1]; //~ ERROR index out of bounds
 
 fn main() {
-    let _e = [6u8][1];
+    let _e = [6u8][1]; //~ ERROR: array index out of bounds
 }
index 45e8fc37d878b60dddd0be3089b057ea680a2522..816799eabf792eb3063865ea2af74a118f7e174d 100644 (file)
@@ -21,7 +21,6 @@ fn main() {
     //~^ WARN attempted to negate with overflow
     let b = 200u8 + 200u8 + 200u8;
     //~^ WARN attempted to add with overflow
-    //~^^ WARN attempted to add with overflow
     let c = 200u8 * 4;
     //~^ WARN attempted to multiply with overflow
     let d = 42u8 - (42u8 + 1);
index e1ed21877c9f6e6e19a008a2099679ba71372973..a3ae0671c54cb2213a35f75df5bc4d3257859d9e 100644 (file)
 fn main() {
       let n = 1u8 << 7;
       let n = 1u8 << 8;   //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift left with overflow
       let n = 1u16 << 15;
       let n = 1u16 << 16; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift left with overflow
       let n = 1u32 << 31;
       let n = 1u32 << 32; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift left with overflow
       let n = 1u64 << 63;
       let n = 1u64 << 64; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift left with overflow
       let n = 1i8 << 7;
       let n = 1i8 << 8;   //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift left with overflow
       let n = 1i16 << 15;
       let n = 1i16 << 16; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift left with overflow
       let n = 1i32 << 31;
       let n = 1i32 << 32; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift left with overflow
       let n = 1i64 << 63;
       let n = 1i64 << 64; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift left with overflow
 
       let n = 1u8 >> 7;
       let n = 1u8 >> 8;   //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift right with overflow
       let n = 1u16 >> 15;
       let n = 1u16 >> 16; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift right with overflow
       let n = 1u32 >> 31;
       let n = 1u32 >> 32; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift right with overflow
       let n = 1u64 >> 63;
       let n = 1u64 >> 64; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift right with overflow
       let n = 1i8 >> 7;
       let n = 1i8 >> 8;   //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift right with overflow
       let n = 1i16 >> 15;
       let n = 1i16 >> 16; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift right with overflow
       let n = 1i32 >> 31;
       let n = 1i32 >> 32; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift right with overflow
       let n = 1i64 >> 63;
       let n = 1i64 >> 64; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift right with overflow
 
       let n = 1u8;
       let n = n << 7;
       let n = n << 8; //~ ERROR: bitshift exceeds the type's number of bits
 
       let n = 1u8 << -8; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift by a negative amount
 
       let n = 1u8 << (4+3);
       let n = 1u8 << (4+4); //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift left with overflow
 
       #[cfg(target_pointer_width = "32")]
       const BITS: usize = 32;
@@ -63,11 +81,14 @@ fn main() {
       const BITS: usize = 64;
 
       let n = 1_isize << BITS; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift left with overflow
       let n = 1_usize << BITS; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift left with overflow
 
 
       let n = 1i8<<(1isize+-1);
 
       let n = 1i64 >> [63][0];
       let n = 1i64 >> [64][0]; //~ ERROR: bitshift exceeds the type's number of bits
+      //~^ WARN: attempted to shift right with overflow
 }
index 83300f18c3e95b6f401f8f506dbd7503dacbaabc..e99dfb9aa0f0e9b6a425e6c9329ff3896feb9899 100644 (file)
 //
 
 #![deny(overflowing_literals)]
+#![deny(const_err)]
 
 #[allow(unused_variables)]
 fn main() {
     let x2: i8 = --128; //~ error: literal out of range for i8
+    //~^ error: attempted to negate with overflow
 
     let x = -3.40282348e+38_f32; //~ error: literal out of range for f32
     let x =  3.40282348e+38_f32; //~ error: literal out of range for f32