diff options
| author | bors <bors@rust-lang.org> | 2015-05-26 09:49:36 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-05-26 09:49:36 +0000 |
| commit | 8a872943ff0fac763eefa52de1ffb1344e698d98 (patch) | |
| tree | 5f32fff3a69b8d16d93f01375175527c2199f742 /src | |
| parent | 7cb9914fceaeaa6a39add43d3da15bb6e1d191f6 (diff) | |
| parent | 43502adf071392df3dd74f019f6973d4b757e7d7 (diff) | |
| download | rust-8a872943ff0fac763eefa52de1ffb1344e698d98.tar.gz rust-8a872943ff0fac763eefa52de1ffb1344e698d98.zip | |
Auto merge of #25778 - econoplas:master, r=pnkfelix
A regression was introduced by commit https://github.com/rust-lang/rust/commit/7b1916d25347913fce3e336517ef22025ccd875f #25612. Negative signed integer literals less than -9223372036854775808i64 were no longer properly reported as #[warn(overflowing_literals)]. Also adding missing test cases to test/compile-fail/lint-type-overflow.rs which could have detected the regression. Further explanation: The expression `(negative && v > max as u64 + 1)` relies on the fact that algebraically speaking `-min == max + 1` to avoid negation and removing the need for `min` completely. If i128 or i256 are ever added, it should also work for these types without requiring a change to `min != i64::MIN &&` also simplifying maintenance. r? @pnkfelix
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_lint/builtin.rs | 6 | ||||
| -rw-r--r-- | src/test/compile-fail/lint-type-overflow.rs | 2 |
2 files changed, 6 insertions, 2 deletions
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index e9db80b71ea..50fdeb39105 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -203,10 +203,12 @@ impl LintPass for TypeLimits { } else { t }; - let (min, max) = int_ty_range(int_type); + let (_, max) = int_ty_range(int_type); let negative = self.negated_expr_id == e.id; - if (negative && min != i64::MIN && v > -min as u64) || + // Detect literal value out of range [min, max] inclusive + // avoiding use of -min to prevent overflow/panic + if (negative && v > max as u64 + 1) || (!negative && v > max as u64) { cx.span_lint(OVERFLOWING_LITERALS, e.span, &*format!("literal out of range for {:?}", t)); diff --git a/src/test/compile-fail/lint-type-overflow.rs b/src/test/compile-fail/lint-type-overflow.rs index ed6a0bd37eb..eb5b77f7a45 100644 --- a/src/test/compile-fail/lint-type-overflow.rs +++ b/src/test/compile-fail/lint-type-overflow.rs @@ -52,6 +52,8 @@ fn main() { let x = 9223372036854775808_i64; //~ error: literal out of range for i64 let x = -9223372036854775808_i64; // should be OK let x = 18446744073709551615_i64; //~ error: literal out of range for i64 + let x: i64 = -9223372036854775809; //~ error: literal out of range for i64 + let x = -9223372036854775809_i64; //~ error: literal out of range for i64 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 |
