Add lint check for negating uint literals and variables.

See #11273 and #13318
This commit is contained in:
Falco Hirschenberger 2014-05-03 00:13:26 +02:00
parent 239557de6d
commit 6c26cbb602
14 changed files with 58 additions and 3 deletions

View File

@ -137,7 +137,7 @@ impl rtio::RtioTimer for Timer {
// there are 10^6 nanoseconds in a millisecond, and the parameter is in
// 100ns intervals, so we multiply by 10^4.
let due = -(msecs * 10000) as libc::LARGE_INTEGER;
let due = -(msecs as i64 * 10000) as libc::LARGE_INTEGER;
assert_eq!(unsafe {
imp::SetWaitableTimer(self.obj, &due, 0, ptr::null(),
ptr::mut_null(), 0)
@ -151,7 +151,7 @@ impl rtio::RtioTimer for Timer {
let (tx, rx) = channel();
// see above for the calculation
let due = -(msecs * 10000) as libc::LARGE_INTEGER;
let due = -(msecs as i64 * 10000) as libc::LARGE_INTEGER;
assert_eq!(unsafe {
imp::SetWaitableTimer(self.obj, &due, 0, ptr::null(),
ptr::mut_null(), 0)
@ -167,7 +167,7 @@ impl rtio::RtioTimer for Timer {
let (tx, rx) = channel();
// see above for the calculation
let due = -(msecs * 10000) as libc::LARGE_INTEGER;
let due = -(msecs as i64 * 10000) as libc::LARGE_INTEGER;
assert_eq!(unsafe {
imp::SetWaitableTimer(self.obj, &due, msecs as libc::LONG,
ptr::null(), ptr::mut_null(), 0)

View File

@ -9,6 +9,7 @@
// except according to those terms.
#![allow(non_camel_case_types)]
#![allow(unsigned_negate)]
use metadata::csearch;
use middle::astencode;

View File

@ -91,6 +91,7 @@ pub enum Lint {
AttributeUsage,
UnknownFeatures,
UnknownCrateType,
UnsignedNegate,
ManagedHeapMemory,
OwnedHeapMemory,
@ -390,6 +391,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
default: deny,
}),
("unsigned_negate",
LintSpec {
lint: UnsignedNegate,
desc: "using an unary minus operator on unsigned type",
default: warn
}),
("unused_must_use",
LintSpec {
lint: UnusedMustUse,
@ -704,6 +712,29 @@ fn check_unused_casts(cx: &Context, e: &ast::Expr) {
fn check_type_limits(cx: &Context, e: &ast::Expr) {
return match e.node {
ast::ExprUnary(ast::UnNeg, ex) => {
match ex.node {
ast::ExprLit(lit) => {
match lit.node {
ast::LitUint(..) => {
cx.span_lint(UnsignedNegate, e.span,
"negation of unsigned int literal may be unintentional");
},
_ => ()
}
},
_ => {
let t = ty::expr_ty(cx.tcx, ex);
match ty::get(t).sty {
ty::ty_uint(_) => {
cx.span_lint(UnsignedNegate, e.span,
"negation of unsigned int variable may be unintentional");
},
_ => ()
}
}
}
},
ast::ExprBinary(binop, l, r) => {
if is_comparison(binop) && !check_limits(cx.tcx, binop, l, r) {
cx.span_lint(TypeLimits, e.span,

View File

@ -43,6 +43,8 @@
* taken to it, implementing them for Rust seems difficult.
*/
#![allow(unsigned_negate)]
use std::container::Map;
use libc::c_ulonglong;
use std::num::{Bitwise};

View File

@ -12,6 +12,8 @@
// FIXME: #6220 Implement floating point formatting
#![allow(unsigned_negate)]
use container::Container;
use fmt;
use iter::{Iterator, DoubleEndedIterator};

View File

@ -11,6 +11,7 @@
//! Operations and constants for 32-bits floats (`f32` type)
#![allow(missing_doc)]
#![allow(unsigned_negate)]
use prelude::*;

View File

@ -11,6 +11,7 @@
//! Operations and constants for unsigned 16-bits integers (`u16` type)
#![allow(non_uppercase_statics)]
#![allow(unsigned_negate)]
use prelude::*;

View File

@ -11,6 +11,7 @@
//! Operations and constants for unsigned 32-bits integers (`u32` type)
#![allow(non_uppercase_statics)]
#![allow(unsigned_negate)]
use prelude::*;

View File

@ -11,6 +11,7 @@
//! Operations and constants for unsigned 64-bits integer (`u64` type)
#![allow(non_uppercase_statics)]
#![allow(unsigned_negate)]
use prelude::*;

View File

@ -11,6 +11,7 @@
//! Operations and constants for unsigned 8-bits integers (`u8` type)
#![allow(non_uppercase_statics)]
#![allow(unsigned_negate)]
use prelude::*;

View File

@ -11,6 +11,7 @@
//! Operations and constants for architecture-sized unsigned integers (`uint` type)
#![allow(non_uppercase_statics)]
#![allow(unsigned_negate)]
use prelude::*;

View File

@ -10,6 +10,7 @@
#![macro_escape]
#![doc(hidden)]
#![allow(unsigned_negate)]
macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (

View File

@ -15,6 +15,7 @@
//! which are not used for scheduling in any way.
#![allow(non_camel_case_types)]
#![allow(unsigned_negate)]
use cast;
use kinds::Send;

View File

@ -36,3 +36,14 @@ fn qux() {
i += 1;
}
}
fn quy() {
let i = -23u; //~ WARNING negation of unsigned int literal may be unintentional
//~^ WARNING unused variable
}
fn quz() {
let i = 23u;
let j = -i; //~ WARNING negation of unsigned int variable may be unintentional
//~^ WARNING unused variable
}