Skip to content

Commit

Permalink
Auto merge of #119432 - gurry:117949-make-lint-run-on-promoteds, r=<try>
Browse files Browse the repository at this point in the history
Make `ConstPropLint` lint run on promoteds

Fixes #117949 wherein the lint didn't fire for the following promoteds:

- SHL or SHR operators in a non-optimized build
- any arithmetic operator in an optimized build

What I have done here is simply enabled `ConstPropLint` to run on promoted bodies by removing the relevant `if` check.

After this change _all_ promoted arithmetic operators will lint _in both non-optimized and optimized builds_. On the flip side programs containing the above mentioned overflowing promoteds that were accepted earlier will now be rejected. Hope that is okay from a backward compatibility standpoint.

I have added tests covering all overflowing promoted & non-promoted ops for both compile-time and runtime operations and for optimized as well as non-optimized builds.

I had to amend some existing tests to make them pass and had to delete a couple that were set to pass despite overflows.

This PR increases the number of duplicate diagnostics emitted (because the same operator might get linted in both the promoted MIR and the main MIR). I hope that is an acceptable trade-off given that we now lint overflows much more comprehensively than earlier.
  • Loading branch information
bors committed Jan 4, 2024
2 parents 090d5ea + ecadc52 commit 8a1050b
Show file tree
Hide file tree
Showing 21 changed files with 5,879 additions and 23 deletions.
5 changes: 0 additions & 5 deletions compiler/rustc_mir_transform/src/const_prop_lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ impl<'tcx> MirLint<'tcx> for ConstPropLint {
return;
}

// will be evaluated by miri and produce its errors there
if body.source.promoted.is_some() {
return;
}

let def_id = body.source.def_id().expect_local();
let def_kind = tcx.def_kind(def_id);
let is_fn_like = def_kind.is_fn_like();
Expand Down
7 changes: 6 additions & 1 deletion src/tools/miri/tests/pass/overflow_checks_off.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
//@compile-flags: -C overflow-checks=off

// Check that we correctly implement the intended behavior of these operators
// when they are not being overflow-checked.
// when they are not being overflow-checked at runtime.

// FIXME: if we call the functions in `std::ops`, we still get the panics.
// Miri does not implement the codegen-time hack that backs `#[rustc_inherit_overflow_checks]`.
// use std::ops::*;


// Disable _compile-time_ overflow linting
// so that we can test runtime overflow checks
#![allow(arithmetic_overflow)]

fn main() {
assert_eq!(-{ -0x80i8 }, -0x80);

Expand Down
8 changes: 4 additions & 4 deletions tests/ui/associated-consts/defaults-cyclic-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ note: ...which requires const-evaluating + checking `Tr::B`...
LL | const B: u8 = Self::A;
| ^^^^^^^
= note: ...which again requires simplifying constant for the type system `Tr::A`, completing the cycle
note: cycle used when const-evaluating + checking `main::promoted[1]`
--> $DIR/defaults-cyclic-fail.rs:16:16
note: cycle used when simplifying constant for the type system `Tr::A`
--> $DIR/defaults-cyclic-fail.rs:5:5
|
LL | assert_eq!(<() as Tr>::A, 0);
| ^^^^^^^^^^^^^
LL | const A: u8 = Self::B;
| ^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to 1 previous error
Expand Down
8 changes: 8 additions & 0 deletions tests/ui/associated-consts/defaults-not-assumed-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ note: erroneous constant encountered
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
| ^^^^^^^^^^^^^

note: erroneous constant encountered
--> $DIR/defaults-not-assumed-fail.rs:33:16
|
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
| ^^^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

note: erroneous constant encountered
--> $DIR/defaults-not-assumed-fail.rs:33:5
|
Expand Down
8 changes: 8 additions & 0 deletions tests/ui/consts/const-eval/issue-44578.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ note: erroneous constant encountered
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

note: erroneous constant encountered
--> $DIR/issue-44578.rs:25:20
|
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

note: erroneous constant encountered
--> $DIR/issue-44578.rs:25:20
|
Expand Down
1 change: 1 addition & 0 deletions tests/ui/consts/const-eval/issue-50814.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct Sum<A, B>(A, B);
impl<A: Unsigned, B: Unsigned> Unsigned for Sum<A, B> {
const MAX: u8 = A::MAX + B::MAX;
//~^ ERROR evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
//~| ERROR evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
}

fn foo<T>(_: T) -> &'static u8 {
Expand Down
22 changes: 19 additions & 3 deletions tests/ui/consts/const-eval/issue-50814.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,33 @@ LL | const MAX: u8 = A::MAX + B::MAX;
| ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow

note: erroneous constant encountered
--> $DIR/issue-50814.rs:20:6
--> $DIR/issue-50814.rs:21:6
|
LL | &Sum::<U8, U8>::MAX
| ^^^^^^^^^^^^^^^^^^

error[E0080]: evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
--> $DIR/issue-50814.rs:15:21
|
LL | const MAX: u8 = A::MAX + B::MAX;
| ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

note: erroneous constant encountered
--> $DIR/issue-50814.rs:21:6
|
LL | &Sum::<U8, U8>::MAX
| ^^^^^^^^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

note: the above error was encountered while instantiating `fn foo::<i32>`
--> $DIR/issue-50814.rs:25:5
--> $DIR/issue-50814.rs:26:5
|
LL | foo(0);
| ^^^^^^

error: aborting due to 1 previous error
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0080`.
3 changes: 1 addition & 2 deletions tests/ui/consts/promotion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ fn main() {
assert_static(&["d", "e", "f"]);
assert_eq!(C, 42);

// make sure that these do not cause trouble despite overflowing
// make sure that this does not cause trouble despite overflowing
assert_static(&(0-1));
assert_static(&-i32::MIN);

// div-by-non-0 is okay
assert_static(&(1/1));
Expand Down
54 changes: 54 additions & 0 deletions tests/ui/lint/issue-117949.noopt.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:16:24
|
LL | format_args!("{}", 5 * i32::MAX);
| ^^^^^^^^^^^^ attempt to compute `5_i32 * i32::MAX`, which would overflow
|
= note: `#[deny(arithmetic_overflow)]` on by default

error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:15:24
|
LL | format_args!("{}", -5 - i32::MAX);
| ^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow

error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:14:24
|
LL | format_args!("{}", 1 + i32::MAX);
| ^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow

error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:13:24
|
LL | format_args!("{}", 1 >> 32);
| ^^^^^^^ attempt to shift right by `32_i32`, which would overflow

error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:12:24
|
LL | format_args!("{}", 1 << 32);
| ^^^^^^^ attempt to shift left by `32_i32`, which would overflow

error: this operation will panic at runtime
--> $DIR/issue-117949.rs:17:24
|
LL | format_args!("{}", 1 / 0);
| ^^^^^ attempt to divide `1_i32` by zero
|
= note: `#[deny(unconditional_panic)]` on by default

error: this operation will panic at runtime
--> $DIR/issue-117949.rs:18:24
|
LL | format_args!("{}", 1 % 0);
| ^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero

error: this operation will panic at runtime
--> $DIR/issue-117949.rs:19:24
|
LL | format_args!("{}", [1, 2, 3][4]);
| ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4

error: aborting due to 8 previous errors

54 changes: 54 additions & 0 deletions tests/ui/lint/issue-117949.opt.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:16:24
|
LL | format_args!("{}", 5 * i32::MAX);
| ^^^^^^^^^^^^ attempt to compute `5_i32 * i32::MAX`, which would overflow
|
= note: `#[deny(arithmetic_overflow)]` on by default

error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:15:24
|
LL | format_args!("{}", -5 - i32::MAX);
| ^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow

error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:14:24
|
LL | format_args!("{}", 1 + i32::MAX);
| ^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow

error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:13:24
|
LL | format_args!("{}", 1 >> 32);
| ^^^^^^^ attempt to shift right by `32_i32`, which would overflow

error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:12:24
|
LL | format_args!("{}", 1 << 32);
| ^^^^^^^ attempt to shift left by `32_i32`, which would overflow

error: this operation will panic at runtime
--> $DIR/issue-117949.rs:17:24
|
LL | format_args!("{}", 1 / 0);
| ^^^^^ attempt to divide `1_i32` by zero
|
= note: `#[deny(unconditional_panic)]` on by default

error: this operation will panic at runtime
--> $DIR/issue-117949.rs:18:24
|
LL | format_args!("{}", 1 % 0);
| ^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero

error: this operation will panic at runtime
--> $DIR/issue-117949.rs:19:24
|
LL | format_args!("{}", [1, 2, 3][4]);
| ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4

error: aborting due to 8 previous errors

54 changes: 54 additions & 0 deletions tests/ui/lint/issue-117949.opt_with_overflow_checks.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:16:24
|
LL | format_args!("{}", 5 * i32::MAX);
| ^^^^^^^^^^^^ attempt to compute `5_i32 * i32::MAX`, which would overflow
|
= note: `#[deny(arithmetic_overflow)]` on by default

error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:15:24
|
LL | format_args!("{}", -5 - i32::MAX);
| ^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow

error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:14:24
|
LL | format_args!("{}", 1 + i32::MAX);
| ^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow

error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:13:24
|
LL | format_args!("{}", 1 >> 32);
| ^^^^^^^ attempt to shift right by `32_i32`, which would overflow

error: this arithmetic operation will overflow
--> $DIR/issue-117949.rs:12:24
|
LL | format_args!("{}", 1 << 32);
| ^^^^^^^ attempt to shift left by `32_i32`, which would overflow

error: this operation will panic at runtime
--> $DIR/issue-117949.rs:17:24
|
LL | format_args!("{}", 1 / 0);
| ^^^^^ attempt to divide `1_i32` by zero
|
= note: `#[deny(unconditional_panic)]` on by default

error: this operation will panic at runtime
--> $DIR/issue-117949.rs:18:24
|
LL | format_args!("{}", 1 % 0);
| ^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero

error: this operation will panic at runtime
--> $DIR/issue-117949.rs:19:24
|
LL | format_args!("{}", [1, 2, 3][4]);
| ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4

error: aborting due to 8 previous errors

20 changes: 20 additions & 0 deletions tests/ui/lint/issue-117949.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Regression test for issue #117949

// revisions: noopt opt opt_with_overflow_checks
//[noopt]compile-flags: -C opt-level=0 -Z deduplicate-diagnostics=yes
//[opt]compile-flags: -O
//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O -Z deduplicate-diagnostics=yes
// build-fail
// ignore-pass (test tests codegen-time behaviour)


fn main() {
format_args!("{}", 1 << 32); //~ ERROR: arithmetic operation will overflow
format_args!("{}", 1 >> 32); //~ ERROR: arithmetic operation will overflow
format_args!("{}", 1 + i32::MAX); //~ ERROR: arithmetic operation will overflow
format_args!("{}", -5 - i32::MAX); //~ ERROR: arithmetic operation will overflow
format_args!("{}", 5 * i32::MAX); //~ ERROR: arithmetic operation will overflow
format_args!("{}", 1 / 0); //~ ERROR: this operation will panic at runtime
format_args!("{}", 1 % 0); //~ ERROR: this operation will panic at runtime
format_args!("{}", [1, 2, 3][4]); //~ ERROR: this operation will panic at runtime
}
Loading

0 comments on commit 8a1050b

Please sign in to comment.