-
Notifications
You must be signed in to change notification settings - Fork 14.1k
Fix const_err with -(-0.0)
#64063
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
Fix const_err with -(-0.0)
#64063
Changes from 6 commits
35c9e5f
3a6aada
4a0872b
8e9825a
0cd9c16
a937d8c
41deb83
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -405,13 +405,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { | |
| } | ||
|
|
||
| let arg = self.eval_operand(arg, source_info)?; | ||
| let oflo_check = self.tcx.sess.overflow_checks(); | ||
| let val = self.use_ecx(source_info, |this| { | ||
| let prim = this.ecx.read_immediate(arg)?; | ||
| match op { | ||
| UnOp::Neg => { | ||
JohnTitor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // Need to do overflow check here: For actual CTFE, MIR | ||
| // generation emits code that does this before calling the op. | ||
| if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { | ||
| // We check overflow in debug mode already | ||
| // so should only check in release mode. | ||
| if !oflo_check | ||
| && prim.layout.ty.is_signed() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. essentially this condition the only needed thing for the fix. The rest is what's causing the CI failure |
||
| && prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { | ||
| throw_panic!(OverflowNeg) | ||
| } | ||
| } | ||
|
|
@@ -485,7 +488,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { | |
| Scalar::from_bool(overflow).into(), | ||
| ) | ||
| } else { | ||
| if overflow { | ||
| // We check overflow in debug mode already | ||
| // so should only check in release mode. | ||
| if !self.tcx.sess.overflow_checks() && overflow { | ||
| let err = err_panic!(Overflow(op)).into(); | ||
| let _: Option<()> = self.use_ecx(source_info, |_| Err(err)); | ||
| return None; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| // needed because negating int::MIN will behave differently between | ||
| // optimized compilation and unoptimized compilation and thus would | ||
| // lead to different lints being emitted | ||
| // compile-flags: -C overflow-checks=on -O | ||
|
|
||
| #![feature(rustc_attrs)] | ||
| #![allow(exceeding_bitshifts)] | ||
|
|
||
| #![deny(const_err)] | ||
|
|
||
| fn black_box<T>(_: T) { | ||
| unimplemented!() | ||
| } | ||
|
|
||
| fn main() { | ||
| let a = -std::i8::MIN; | ||
| //~^ ERROR const_err | ||
| let b = 200u8 + 200u8 + 200u8; | ||
| //~^ ERROR const_err | ||
| let c = 200u8 * 4; | ||
| //~^ ERROR const_err | ||
| let d = 42u8 - (42u8 + 1); | ||
| //~^ ERROR const_err | ||
| let _e = [5u8][1]; | ||
| //~^ ERROR const_err | ||
| black_box(a); | ||
| black_box(b); | ||
| black_box(c); | ||
| black_box(d); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| error: attempt to negate with overflow | ||
| --> $DIR/const-err3.rs:16:13 | ||
| | | ||
| LL | let a = -std::i8::MIN; | ||
| | ^^^^^^^^^^^^^ | ||
| | | ||
| note: lint level defined here | ||
| --> $DIR/const-err3.rs:9:9 | ||
| | | ||
| LL | #![deny(const_err)] | ||
| | ^^^^^^^^^ | ||
|
|
||
| error: attempt to add with overflow | ||
| --> $DIR/const-err3.rs:18:13 | ||
| | | ||
| LL | let b = 200u8 + 200u8 + 200u8; | ||
| | ^^^^^^^^^^^^^ | ||
|
|
||
| error: attempt to multiply with overflow | ||
| --> $DIR/const-err3.rs:20:13 | ||
| | | ||
| LL | let c = 200u8 * 4; | ||
| | ^^^^^^^^^ | ||
|
|
||
| error: attempt to subtract with overflow | ||
| --> $DIR/const-err3.rs:22:13 | ||
| | | ||
| LL | let d = 42u8 - (42u8 + 1); | ||
| | ^^^^^^^^^^^^^^^^^ | ||
|
|
||
| error: index out of bounds: the len is 1 but the index is 1 | ||
| --> $DIR/const-err3.rs:24:14 | ||
| | | ||
| LL | let _e = [5u8][1]; | ||
| | ^^^^^^^^ | ||
|
|
||
| error: aborting due to 5 previous errors | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // compile-flags: -C overflow-checks=on -O | ||
|
|
||
| #![deny(const_err)] | ||
|
|
||
| fn main() { | ||
| println!("{}", 0u32 - 1); | ||
| //~^ ERROR attempt to subtract with overflow | ||
| let _x = 0u32 - 1; | ||
| //~^ ERROR attempt to subtract with overflow | ||
| println!("{}", 1/(1-1)); | ||
| //~^ ERROR attempt to divide by zero [const_err] | ||
| //~| ERROR reaching this expression at runtime will panic or abort [const_err] | ||
| let _x = 1/(1-1); | ||
| //~^ ERROR const_err | ||
| //~| ERROR const_err | ||
| println!("{}", 1/(false as u32)); | ||
| //~^ ERROR attempt to divide by zero [const_err] | ||
| //~| ERROR reaching this expression at runtime will panic or abort [const_err] | ||
| let _x = 1/(false as u32); | ||
| //~^ ERROR const_err | ||
| //~| ERROR const_err | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| error: attempt to subtract with overflow | ||
| --> $DIR/promoted_errors2.rs:6:20 | ||
| | | ||
| LL | println!("{}", 0u32 - 1); | ||
| | ^^^^^^^^ | ||
| | | ||
| note: lint level defined here | ||
| --> $DIR/promoted_errors2.rs:3:9 | ||
| | | ||
| LL | #![deny(const_err)] | ||
| | ^^^^^^^^^ | ||
|
|
||
| error: attempt to subtract with overflow | ||
| --> $DIR/promoted_errors2.rs:8:14 | ||
| | | ||
| LL | let _x = 0u32 - 1; | ||
| | ^^^^^^^^ | ||
|
|
||
| error: attempt to divide by zero | ||
| --> $DIR/promoted_errors2.rs:10:20 | ||
| | | ||
| LL | println!("{}", 1/(1-1)); | ||
| | ^^^^^^^ | ||
|
|
||
| error: reaching this expression at runtime will panic or abort | ||
| --> $DIR/promoted_errors2.rs:10:20 | ||
| | | ||
| LL | println!("{}", 1/(1-1)); | ||
| | ^^^^^^^ attempt to divide by zero | ||
|
|
||
| error: attempt to divide by zero | ||
| --> $DIR/promoted_errors2.rs:13:14 | ||
| | | ||
| LL | let _x = 1/(1-1); | ||
| | ^^^^^^^ | ||
|
|
||
| error: this expression will panic at runtime | ||
| --> $DIR/promoted_errors2.rs:13:14 | ||
| | | ||
| LL | let _x = 1/(1-1); | ||
| | ^^^^^^^ attempt to divide by zero | ||
|
|
||
| error: attempt to divide by zero | ||
| --> $DIR/promoted_errors2.rs:16:20 | ||
| | | ||
| LL | println!("{}", 1/(false as u32)); | ||
| | ^^^^^^^^^^^^^^^^ | ||
|
|
||
| error: reaching this expression at runtime will panic or abort | ||
| --> $DIR/promoted_errors2.rs:16:20 | ||
| | | ||
| LL | println!("{}", 1/(false as u32)); | ||
| | ^^^^^^^^^^^^^^^^ attempt to divide by zero | ||
|
|
||
| error: attempt to divide by zero | ||
| --> $DIR/promoted_errors2.rs:19:14 | ||
| | | ||
| LL | let _x = 1/(false as u32); | ||
| | ^^^^^^^^^^^^^^^^ | ||
|
|
||
| error: this expression will panic at runtime | ||
| --> $DIR/promoted_errors2.rs:19:14 | ||
| | | ||
| LL | let _x = 1/(false as u32); | ||
| | ^^^^^^^^^^^^^^^^ attempt to divide by zero | ||
|
|
||
| error: aborting due to 10 previous errors | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| // compile-flags: -C overflow-checks=on -O | ||
| // run-pass | ||
|
|
||
| fn main() { | ||
| let _ = -(-0.0); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| // run-pass | ||
|
|
||
| fn main() { | ||
| let _ = -(-0.0); | ||
| } |
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,59 @@ | ||||
| // compile-flags: -C overflow-checks=on -O | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe noopt overwrites this
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The weird thing is that it happened in
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh. That may explain it... not sure what the best thing to do here is. Maybe instead of copying the files we should use the scheme where one test is built in multiple modes? I forget what the appropriate flags are, but incremental has loads of them
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or could we add the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If that solves it, sure
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added the flag to the test, could we run
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can test this locally by setting Line 355 in b9de4ef
config.toml
Unfortunately
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I didn't know that. |
||||
|
|
||||
| #![deny(const_err)] | ||||
|
|
||||
| use std::{isize, i8, i16, i32, i64}; | ||||
| use std::thread; | ||||
|
|
||||
| fn main() { | ||||
| assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); | ||||
| //~^ ERROR attempt to divide with overflow | ||||
| assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); | ||||
| //~^ ERROR attempt to divide with overflow | ||||
| assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); | ||||
| //~^ ERROR attempt to divide with overflow | ||||
| assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); | ||||
| //~^ ERROR attempt to divide with overflow | ||||
| assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); | ||||
| //~^ ERROR attempt to divide with overflow | ||||
| assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); | ||||
| //~^ ERROR attempt to divide by zero | ||||
| //~| ERROR this expression will panic at runtime | ||||
| assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); | ||||
| //~^ ERROR attempt to divide by zero | ||||
| //~| ERROR this expression will panic at runtime | ||||
| assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); | ||||
| //~^ ERROR attempt to divide by zero | ||||
| //~| ERROR this expression will panic at runtime | ||||
| assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); | ||||
| //~^ ERROR attempt to divide by zero | ||||
| //~| ERROR this expression will panic at runtime | ||||
| assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); | ||||
| //~^ ERROR attempt to divide by zero | ||||
| //~| ERROR this expression will panic at runtime | ||||
| assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); | ||||
| //~^ ERROR attempt to calculate the remainder with overflow | ||||
| assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); | ||||
| //~^ ERROR attempt to calculate the remainder with overflow | ||||
| assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); | ||||
| //~^ ERROR attempt to calculate the remainder with overflow | ||||
| assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); | ||||
| //~^ ERROR attempt to calculate the remainder with overflow | ||||
| assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); | ||||
| //~^ ERROR attempt to calculate the remainder with overflow | ||||
| assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); | ||||
| //~^ ERROR attempt to calculate the remainder with a divisor of zero | ||||
| //~| ERROR this expression will panic at runtime | ||||
| assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); | ||||
| //~^ ERROR attempt to calculate the remainder with a divisor of zero | ||||
| //~| ERROR this expression will panic at runtime | ||||
| assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); | ||||
| //~^ ERROR attempt to calculate the remainder with a divisor of zero | ||||
| //~| ERROR this expression will panic at runtime | ||||
| assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); | ||||
| //~^ ERROR attempt to calculate the remainder with a divisor of zero | ||||
| //~| ERROR this expression will panic at runtime | ||||
| assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); | ||||
| //~^ ERROR attempt to calculate the remainder with a divisor of zero | ||||
| //~| ERROR this expression will panic at runtime | ||||
| } | ||||
Uh oh!
There was an error while loading. Please reload this page.