Skip to content

Add lint check for negating uint literals and variables. #13579

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 3, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/libnative/io/timer_win32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions src/librustc/middle/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// except according to those terms.

#![allow(non_camel_case_types)]
#![allow(unsigned_negate)]

use metadata::csearch;
use middle::astencode;
Expand Down
31 changes: 31 additions & 0 deletions src/librustc/middle/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ pub enum Lint {
AttributeUsage,
UnknownFeatures,
UnknownCrateType,
UnsignedNegate,

ManagedHeapMemory,
OwnedHeapMemory,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/middle/trans/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
2 changes: 2 additions & 0 deletions src/libstd/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

// FIXME: #6220 Implement floating point formatting

#![allow(unsigned_negate)]

use container::Container;
use fmt;
use iter::{Iterator, DoubleEndedIterator};
Expand Down
1 change: 1 addition & 0 deletions src/libstd/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! Operations and constants for 32-bits floats (`f32` type)

#![allow(missing_doc)]
#![allow(unsigned_negate)]

use prelude::*;

Expand Down
1 change: 1 addition & 0 deletions src/libstd/num/u16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! Operations and constants for unsigned 16-bits integers (`u16` type)

#![allow(non_uppercase_statics)]
#![allow(unsigned_negate)]

use prelude::*;

Expand Down
1 change: 1 addition & 0 deletions src/libstd/num/u32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! Operations and constants for unsigned 32-bits integers (`u32` type)

#![allow(non_uppercase_statics)]
#![allow(unsigned_negate)]

use prelude::*;

Expand Down
1 change: 1 addition & 0 deletions src/libstd/num/u64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! Operations and constants for unsigned 64-bits integer (`u64` type)

#![allow(non_uppercase_statics)]
#![allow(unsigned_negate)]

use prelude::*;

Expand Down
1 change: 1 addition & 0 deletions src/libstd/num/u8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! Operations and constants for unsigned 8-bits integers (`u8` type)

#![allow(non_uppercase_statics)]
#![allow(unsigned_negate)]

use prelude::*;

Expand Down
1 change: 1 addition & 0 deletions src/libstd/num/uint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! Operations and constants for architecture-sized unsigned integers (`uint` type)

#![allow(non_uppercase_statics)]
#![allow(unsigned_negate)]

use prelude::*;

Expand Down
1 change: 1 addition & 0 deletions src/libstd/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#![macro_escape]
#![doc(hidden)]
#![allow(unsigned_negate)]

macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (

Expand Down
1 change: 1 addition & 0 deletions src/libstd/rt/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions src/test/compile-fail/lint-type-limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}