const_err lint all constant expressions
This commit is contained in:
parent
ee983230c9
commit
3acee3b6c5
@ -28,8 +28,8 @@ use rustc::dep_graph::DepNode;
|
||||
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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
|
||||
}
|
||||
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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
|
||||
}
|
||||
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);
|
||||
|
@ -18,5 +18,5 @@ pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR attempted to subtract with overfl
|
||||
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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -16,46 +16,64 @@
|
||||
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
|
||||
}
|
||||
|
@ -10,10 +10,12 @@
|
||||
//
|
||||
|
||||
#![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
|
||||
|
Loading…
x
Reference in New Issue
Block a user