From 32b903d87768dbc9acf497b1646b20069d9bf212 Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Mon, 3 Nov 2014 20:08:11 +0100 Subject: [PATCH] Also fix undefined behaviour when shift equals the number of bits LLVM states: "If op2 is (statically or dynamically) negative or equal to or larger than the number of bits in op1, the result is undefined." --- src/librustc/lint/builtin.rs | 6 +- .../compile-fail/lint-exceeding-bitshifts.rs | 74 +++++++++---------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 76ef6206d64..2b145192131 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -187,12 +187,12 @@ impl LintPass for TypeLimits { if let Some(bits) = opt_ty_bits { let exceeding = if let ast::ExprLit(ref lit) = r.node { - if let ast::LitInt(shift, _) = lit.node { shift > bits } + if let ast::LitInt(shift, _) = lit.node { shift >= bits } else { false } } else { match eval_const_expr_partial(cx.tcx, &**r) { - Ok(const_int(shift)) => { shift as u64 > bits }, - Ok(const_uint(shift)) => { shift > bits }, + Ok(const_int(shift)) => { shift as u64 >= bits }, + Ok(const_uint(shift)) => { shift >= bits }, _ => { false } } }; diff --git a/src/test/compile-fail/lint-exceeding-bitshifts.rs b/src/test/compile-fail/lint-exceeding-bitshifts.rs index f270994bd38..eecc2168029 100644 --- a/src/test/compile-fail/lint-exceeding-bitshifts.rs +++ b/src/test/compile-fail/lint-exceeding-bitshifts.rs @@ -12,47 +12,47 @@ #![allow(unused_variables)] fn main() { - let n = 1u8 << 8; - let n = 1u8 << 9; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1u16 << 16; - let n = 1u16 << 17; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1u32 << 32; - let n = 1u32 << 33; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1u64 << 64; - let n = 1u64 << 65; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1i8 << 8; - let n = 1i8 << 9; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1i16 << 16; - let n = 1i16 << 17; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1i32 << 32; - let n = 1i32 << 33; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1i64 << 64; - let n = 1i64 << 65; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1u8 << 7; + let n = 1u8 << 8; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1u16 << 15; + let n = 1u16 << 16; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1u32 << 31; + let n = 1u32 << 32; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1u64 << 63; + let n = 1u64 << 64; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1i8 << 7; + let n = 1i8 << 8; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1i16 << 15; + let n = 1i16 << 16; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1i32 << 31; + let n = 1i32 << 32; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1i64 << 63; + let n = 1i64 << 64; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1u8 >> 8; - let n = 1u8 >> 9; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1u16 >> 16; - let n = 1u16 >> 17; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1u32 >> 32; - let n = 1u32 >> 33; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1u64 >> 64; - let n = 1u64 >> 65; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1i8 >> 8; - let n = 1i8 >> 9; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1i16 >> 16; - let n = 1i16 >> 17; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1i32 >> 32; - let n = 1i32 >> 33; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1i64 >> 64; - let n = 1i64 >> 65; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1u8 >> 7; + let n = 1u8 >> 8; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1u16 >> 15; + let n = 1u16 >> 16; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1u32 >> 31; + let n = 1u32 >> 32; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1u64 >> 63; + let n = 1u64 >> 64; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1i8 >> 7; + let n = 1i8 >> 8; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1i16 >> 15; + let n = 1i16 >> 16; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1i32 >> 31; + let n = 1i32 >> 32; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1i64 >> 63; + let n = 1i64 >> 64; //~ ERROR: bitshift exceeds the type's number of bits let n = 1u8; - let n = n << 8; - let n = n << 9; //~ ERROR: bitshift exceeds the type's number of bits + let n = n << 7; + let n = n << 8; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1u8 << -9; //~ ERROR: bitshift exceeds the type's number of bits + let n = 1u8 << -8; //~ ERROR: bitshift exceeds the type's number of bits - let n = 1u8 << (4+4); - let n = 1u8 << (4+5); //~ ERROR: bitshift exceeds the type's number of bits + let n = 1u8 << (4+3); + let n = 1u8 << (4+4); //~ ERROR: bitshift exceeds the type's number of bits }