avoid promoting division, modulo and indexing operations that could fail
This commit is contained in:
parent
dc1eee2f25
commit
5be27b7a70
|
@ -505,6 +505,10 @@ impl<'tcx> Validator<'_, 'tcx> {
|
|||
ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {}
|
||||
|
||||
ProjectionElem::Index(local) => {
|
||||
// This could be OOB, so reject for implicit promotion.
|
||||
if !self.explicit {
|
||||
return Err(Unpromotable);
|
||||
}
|
||||
self.validate_local(local)?;
|
||||
}
|
||||
|
||||
|
@ -589,9 +593,7 @@ impl<'tcx> Validator<'_, 'tcx> {
|
|||
|
||||
fn validate_rvalue(&self, rvalue: &Rvalue<'tcx>) -> Result<(), Unpromotable> {
|
||||
match rvalue {
|
||||
Rvalue::Use(operand)
|
||||
| Rvalue::Repeat(operand, _)
|
||||
| Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, operand) => {
|
||||
Rvalue::Use(operand) | Rvalue::Repeat(operand, _) => {
|
||||
self.validate_operand(operand)?;
|
||||
}
|
||||
|
||||
|
@ -616,10 +618,26 @@ impl<'tcx> Validator<'_, 'tcx> {
|
|||
self.validate_operand(operand)?;
|
||||
}
|
||||
|
||||
Rvalue::NullaryOp(op, _) => match op {
|
||||
NullOp::Box => return Err(Unpromotable),
|
||||
NullOp::SizeOf => {}
|
||||
},
|
||||
|
||||
Rvalue::UnaryOp(op, operand) => {
|
||||
match op {
|
||||
// These operations can never fail.
|
||||
UnOp::Neg | UnOp::Not => {}
|
||||
}
|
||||
|
||||
self.validate_operand(operand)?;
|
||||
}
|
||||
|
||||
Rvalue::BinaryOp(op, lhs, rhs) | Rvalue::CheckedBinaryOp(op, lhs, rhs) => {
|
||||
let op = *op;
|
||||
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body, self.tcx).kind() {
|
||||
// raw pointer operations are not allowed inside consts and thus not promotable
|
||||
let lhs_ty = lhs.ty(self.body, self.tcx);
|
||||
|
||||
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs_ty.kind() {
|
||||
// Raw and fn pointer operations are not allowed inside consts and thus not promotable.
|
||||
assert!(matches!(
|
||||
op,
|
||||
BinOp::Eq
|
||||
|
@ -634,7 +652,22 @@ impl<'tcx> Validator<'_, 'tcx> {
|
|||
}
|
||||
|
||||
match op {
|
||||
// FIXME: reject operations that can fail -- namely, division and modulo.
|
||||
BinOp::Div | BinOp::Rem => {
|
||||
if !self.explicit && lhs_ty.is_integral() {
|
||||
// Integer division: the RHS must be a non-zero const.
|
||||
let const_val = match rhs {
|
||||
Operand::Constant(c) => {
|
||||
c.literal.try_eval_bits(self.tcx, self.param_env, lhs_ty)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
match const_val {
|
||||
Some(x) if x != 0 => {} // okay
|
||||
_ => return Err(Unpromotable), // value not known or 0 -- not okay
|
||||
}
|
||||
}
|
||||
}
|
||||
// The remaining operations can never fail.
|
||||
BinOp::Eq
|
||||
| BinOp::Ne
|
||||
| BinOp::Le
|
||||
|
@ -645,8 +678,6 @@ impl<'tcx> Validator<'_, 'tcx> {
|
|||
| BinOp::Add
|
||||
| BinOp::Sub
|
||||
| BinOp::Mul
|
||||
| BinOp::Div
|
||||
| BinOp::Rem
|
||||
| BinOp::BitXor
|
||||
| BinOp::BitAnd
|
||||
| BinOp::BitOr
|
||||
|
@ -658,11 +689,6 @@ impl<'tcx> Validator<'_, 'tcx> {
|
|||
self.validate_operand(rhs)?;
|
||||
}
|
||||
|
||||
Rvalue::NullaryOp(op, _) => match op {
|
||||
NullOp::Box => return Err(Unpromotable),
|
||||
NullOp::SizeOf => {}
|
||||
},
|
||||
|
||||
Rvalue::AddressOf(_, place) => {
|
||||
// We accept `&raw *`, i.e., raw reborrows -- creating a raw pointer is
|
||||
// no problem, only using it is.
|
||||
|
|
|
@ -24,41 +24,41 @@ fn main() -> () {
|
|||
}
|
||||
|
||||
alloc0 (static: FOO, size: 8, align: 4) {
|
||||
╾─alloc27─╼ 03 00 00 00 │ ╾──╼....
|
||||
╾─alloc31─╼ 03 00 00 00 │ ╾──╼....
|
||||
}
|
||||
|
||||
alloc27 (size: 48, align: 4) {
|
||||
0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc12─╼ 00 00 00 00 │ ....░░░░╾──╼....
|
||||
0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc17─╼ 02 00 00 00 │ ....░░░░╾──╼....
|
||||
0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc25─╼ 03 00 00 00 │ ....*...╾──╼....
|
||||
alloc31 (size: 48, align: 4) {
|
||||
0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc8──╼ 00 00 00 00 │ ....░░░░╾──╼....
|
||||
0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc14─╼ 02 00 00 00 │ ....░░░░╾──╼....
|
||||
0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc29─╼ 03 00 00 00 │ ....*...╾──╼....
|
||||
}
|
||||
|
||||
alloc12 (size: 0, align: 4) {}
|
||||
alloc8 (size: 0, align: 4) {}
|
||||
|
||||
alloc17 (size: 8, align: 4) {
|
||||
╾─alloc15─╼ ╾─alloc16─╼ │ ╾──╼╾──╼
|
||||
alloc14 (size: 8, align: 4) {
|
||||
╾─alloc12─╼ ╾─alloc13─╼ │ ╾──╼╾──╼
|
||||
}
|
||||
|
||||
alloc15 (size: 1, align: 1) {
|
||||
alloc12 (size: 1, align: 1) {
|
||||
05 │ .
|
||||
}
|
||||
|
||||
alloc16 (size: 1, align: 1) {
|
||||
alloc13 (size: 1, align: 1) {
|
||||
06 │ .
|
||||
}
|
||||
|
||||
alloc25 (size: 12, align: 4) {
|
||||
╾─a21+0x3─╼ ╾─alloc22─╼ ╾─a24+0x2─╼ │ ╾──╼╾──╼╾──╼
|
||||
alloc29 (size: 12, align: 4) {
|
||||
╾─a21+0x3─╼ ╾─alloc23─╼ ╾─a28+0x2─╼ │ ╾──╼╾──╼╾──╼
|
||||
}
|
||||
|
||||
alloc21 (size: 4, align: 1) {
|
||||
2a 45 15 6f │ *E.o
|
||||
}
|
||||
|
||||
alloc22 (size: 1, align: 1) {
|
||||
alloc23 (size: 1, align: 1) {
|
||||
2a │ *
|
||||
}
|
||||
|
||||
alloc24 (size: 4, align: 1) {
|
||||
alloc28 (size: 4, align: 1) {
|
||||
2a 45 15 6f │ *E.o
|
||||
}
|
||||
|
|
|
@ -24,44 +24,44 @@ fn main() -> () {
|
|||
}
|
||||
|
||||
alloc0 (static: FOO, size: 16, align: 8) {
|
||||
╾───────alloc27───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........
|
||||
╾───────alloc31───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........
|
||||
}
|
||||
|
||||
alloc27 (size: 72, align: 8) {
|
||||
0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc12───────╼ │ ....░░░░╾──────╼
|
||||
alloc31 (size: 72, align: 8) {
|
||||
0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc8────────╼ │ ....░░░░╾──────╼
|
||||
0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ │ ............░░░░
|
||||
0x20 │ ╾───────alloc17───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........
|
||||
0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc25───────╼ │ ....*...╾──────╼
|
||||
0x20 │ ╾───────alloc14───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........
|
||||
0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc29───────╼ │ ....*...╾──────╼
|
||||
0x40 │ 03 00 00 00 00 00 00 00 │ ........
|
||||
}
|
||||
|
||||
alloc12 (size: 0, align: 8) {}
|
||||
alloc8 (size: 0, align: 8) {}
|
||||
|
||||
alloc17 (size: 16, align: 8) {
|
||||
╾───────alloc15───────╼ ╾───────alloc16───────╼ │ ╾──────╼╾──────╼
|
||||
alloc14 (size: 16, align: 8) {
|
||||
╾───────alloc12───────╼ ╾───────alloc13───────╼ │ ╾──────╼╾──────╼
|
||||
}
|
||||
|
||||
alloc15 (size: 1, align: 1) {
|
||||
alloc12 (size: 1, align: 1) {
|
||||
05 │ .
|
||||
}
|
||||
|
||||
alloc16 (size: 1, align: 1) {
|
||||
alloc13 (size: 1, align: 1) {
|
||||
06 │ .
|
||||
}
|
||||
|
||||
alloc25 (size: 24, align: 8) {
|
||||
0x00 │ ╾─────alloc21+0x3─────╼ ╾───────alloc22───────╼ │ ╾──────╼╾──────╼
|
||||
0x10 │ ╾─────alloc24+0x2─────╼ │ ╾──────╼
|
||||
alloc29 (size: 24, align: 8) {
|
||||
0x00 │ ╾─────alloc21+0x3─────╼ ╾───────alloc23───────╼ │ ╾──────╼╾──────╼
|
||||
0x10 │ ╾─────alloc28+0x2─────╼ │ ╾──────╼
|
||||
}
|
||||
|
||||
alloc21 (size: 4, align: 1) {
|
||||
2a 45 15 6f │ *E.o
|
||||
}
|
||||
|
||||
alloc22 (size: 1, align: 1) {
|
||||
alloc23 (size: 1, align: 1) {
|
||||
2a │ *
|
||||
}
|
||||
|
||||
alloc24 (size: 4, align: 1) {
|
||||
alloc28 (size: 4, align: 1) {
|
||||
2a 45 15 6f │ *E.o
|
||||
}
|
||||
|
|
|
@ -24,30 +24,30 @@ fn main() -> () {
|
|||
}
|
||||
|
||||
alloc0 (static: FOO, size: 4, align: 4) {
|
||||
╾─alloc10─╼ │ ╾──╼
|
||||
╾─alloc11─╼ │ ╾──╼
|
||||
}
|
||||
|
||||
alloc10 (size: 168, align: 1) {
|
||||
alloc11 (size: 168, align: 1) {
|
||||
0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................
|
||||
0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾─alloc5──╼ │ ............╾──╼
|
||||
0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾─alloc4──╼ │ ............╾──╼
|
||||
0x20 │ 01 ef cd ab 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0x50 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0x80 │ 00 00 00 00 00 00 00 00 00 00 ╾─alloc7──╼ 00 00 │ ..........╾──╼..
|
||||
0x90 │ ╾─a8+0x63─╼ 00 00 00 00 00 00 00 00 00 00 00 00 │ ╾──╼............
|
||||
0x80 │ 00 00 00 00 00 00 00 00 00 00 ╾─alloc6──╼ 00 00 │ ..........╾──╼..
|
||||
0x90 │ ╾─a9+0x63─╼ 00 00 00 00 00 00 00 00 00 00 00 00 │ ╾──╼............
|
||||
0xa0 │ 00 00 00 00 00 00 00 00 │ ........
|
||||
}
|
||||
|
||||
alloc5 (size: 4, align: 4) {
|
||||
alloc4 (size: 4, align: 4) {
|
||||
2a 00 00 00 │ *...
|
||||
}
|
||||
|
||||
alloc7 (fn: main)
|
||||
alloc6 (fn: main)
|
||||
|
||||
alloc8 (size: 100, align: 1) {
|
||||
alloc9 (size: 100, align: 1) {
|
||||
0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
|
|
|
@ -24,12 +24,12 @@ fn main() -> () {
|
|||
}
|
||||
|
||||
alloc0 (static: FOO, size: 8, align: 8) {
|
||||
╾───────alloc10───────╼ │ ╾──────╼
|
||||
╾───────alloc11───────╼ │ ╾──────╼
|
||||
}
|
||||
|
||||
alloc10 (size: 180, align: 1) {
|
||||
alloc11 (size: 180, align: 1) {
|
||||
0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................
|
||||
0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾──alloc5── │ ............╾───
|
||||
0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾──alloc4── │ ............╾───
|
||||
0x20 │ ──────────╼ 01 ef cd ab 00 00 00 00 00 00 00 00 │ ───╼............
|
||||
0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
|
@ -37,18 +37,18 @@ alloc10 (size: 180, align: 1) {
|
|||
0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0x80 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ╾──── │ ..............╾─
|
||||
0x90 │ ─────alloc7─────╼ 00 00 ╾─────alloc8+0x63─────╼ │ ─────╼..╾──────╼
|
||||
0x90 │ ─────alloc6─────╼ 00 00 ╾─────alloc9+0x63─────╼ │ ─────╼..╾──────╼
|
||||
0xa0 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0xb0 │ 00 00 00 00 │ ....
|
||||
}
|
||||
|
||||
alloc5 (size: 4, align: 4) {
|
||||
alloc4 (size: 4, align: 4) {
|
||||
2a 00 00 00 │ *...
|
||||
}
|
||||
|
||||
alloc7 (fn: main)
|
||||
alloc6 (fn: main)
|
||||
|
||||
alloc8 (size: 100, align: 1) {
|
||||
alloc9 (size: 100, align: 1) {
|
||||
0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||
|
|
|
@ -6,6 +6,4 @@
|
|||
fn main() {
|
||||
&{ [1, 2, 3][4] };
|
||||
//~^ WARN operation will panic
|
||||
//~| WARN reaching this expression at runtime will panic or abort
|
||||
//~| WARN erroneous constant used [const_err]
|
||||
}
|
||||
|
|
|
@ -10,25 +10,5 @@ note: the lint level is defined here
|
|||
LL | #![warn(const_err, unconditional_panic)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: reaching this expression at runtime will panic or abort
|
||||
--> $DIR/array-literal-index-oob.rs:7:8
|
||||
|
|
||||
LL | &{ [1, 2, 3][4] };
|
||||
| ---^^^^^^^^^^^^--
|
||||
| |
|
||||
| indexing out of bounds: the len is 3 but the index is 4
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/array-literal-index-oob.rs:4:9
|
||||
|
|
||||
LL | #![warn(const_err, unconditional_panic)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: erroneous constant used
|
||||
--> $DIR/array-literal-index-oob.rs:7:5
|
||||
|
|
||||
LL | &{ [1, 2, 3][4] };
|
||||
| ^^^^^^^^^^^^^^^^^ referenced constant has errors
|
||||
|
||||
warning: 3 warnings emitted
|
||||
warning: 1 warning emitted
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// compile-flags: -Ztreat-err-as-bug
|
||||
//~ERROR constructed but no error reported
|
||||
// compile-flags: -Ztreat-err-as-bug=2
|
||||
// build-fail
|
||||
// failure-status: 101
|
||||
// rustc-env:RUST_BACKTRACE=1
|
||||
|
@ -15,8 +16,11 @@
|
|||
|
||||
#![allow(unconditional_panic)]
|
||||
|
||||
#[warn(const_err)]
|
||||
const X: i32 = 1 / 0; //~WARN any use of this value will cause an error
|
||||
|
||||
fn main() {
|
||||
let x: &'static i32 = &(1 / 0);
|
||||
//~^ ERROR reaching this expression at runtime will panic or abort [const_err]
|
||||
let x: &'static i32 = &X;
|
||||
//~^ ERROR evaluation of constant expression failed
|
||||
println!("x={}", x);
|
||||
}
|
||||
|
|
|
@ -1,18 +1,26 @@
|
|||
error: reaching this expression at runtime will panic or abort
|
||||
--> $DIR/const-eval-query-stack.rs:19:28
|
||||
warning: any use of this value will cause an error
|
||||
--> $DIR/const-eval-query-stack.rs:20:16
|
||||
|
|
||||
LL | let x: &'static i32 = &(1 / 0);
|
||||
| -^^^^^^^
|
||||
| |
|
||||
| dividing by zero
|
||||
LL | const X: i32 = 1 / 0;
|
||||
| ---------------^^^^^-
|
||||
| |
|
||||
| attempt to divide `1_i32` by zero
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
note: the lint level is defined here
|
||||
--> $DIR/const-eval-query-stack.rs:19:8
|
||||
|
|
||||
LL | #[warn(const_err)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0080]: evaluation of constant expression failed
|
||||
--> $DIR/const-eval-query-stack.rs:23:27
|
||||
|
|
||||
LL | let x: &'static i32 = &X;
|
||||
| ^-
|
||||
| |
|
||||
| referenced constant has errors
|
||||
query stack during panic:
|
||||
#0 [eval_to_allocation_raw] const-evaluating + checking `main::promoted[1]`
|
||||
#1 [eval_to_const_value_raw] simplifying constant for the type system `main::promoted[1]`
|
||||
#2 [eval_to_const_value_raw] simplifying constant for the type system `main::promoted[1]`
|
||||
#3 [normalize_generic_arg_after_erasing_regions] normalizing `main::promoted[1]`
|
||||
#4 [optimized_mir] optimizing MIR for `main`
|
||||
#5 [collect_and_partition_mono_items] collect_and_partition_mono_items
|
||||
#0 [normalize_generic_arg_after_erasing_regions] normalizing `main::promoted[1]`
|
||||
#1 [optimized_mir] optimizing MIR for `main`
|
||||
#2 [collect_and_partition_mono_items] collect_and_partition_mono_items
|
||||
end of query stack
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
warning: this arithmetic operation will overflow
|
||||
--> $DIR/promoted_errors.rs:12:20
|
||||
--> $DIR/promoted_errors.rs:13:5
|
||||
|
|
||||
LL | println!("{}", 0u32 - 1);
|
||||
| ^^^^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
|
||||
LL | 0 - 1
|
||||
| ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/promoted_errors.rs:9:20
|
||||
|
@ -10,29 +10,24 @@ note: the lint level is defined here
|
|||
LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: this arithmetic operation will overflow
|
||||
--> $DIR/promoted_errors.rs:14:14
|
||||
warning: any use of this value will cause an error
|
||||
--> $DIR/promoted_errors.rs:13:5
|
||||
|
|
||||
LL | let _x = 0u32 - 1;
|
||||
| ^^^^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
|
||||
|
||||
warning: this operation will panic at runtime
|
||||
--> $DIR/promoted_errors.rs:16:20
|
||||
|
|
||||
LL | println!("{}", 1 / (1 - 1));
|
||||
| ^^^^^^^^^^^ attempt to divide `1_i32` by zero
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/promoted_errors.rs:9:41
|
||||
|
|
||||
LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: reaching this expression at runtime will panic or abort
|
||||
--> $DIR/promoted_errors.rs:16:20
|
||||
|
|
||||
LL | println!("{}", 1 / (1 - 1));
|
||||
| ^^^^^^^^^^^ dividing by zero
|
||||
LL | 0 - 1
|
||||
| ^^^^^
|
||||
| |
|
||||
| attempt to compute `0_u32 - 1_u32`, which would overflow
|
||||
| inside `overflow` at $DIR/promoted_errors.rs:13:5
|
||||
| inside `X` at $DIR/promoted_errors.rs:31:29
|
||||
...
|
||||
LL | / const X: () = {
|
||||
LL | | let _x: &'static u32 = &overflow();
|
||||
LL | |
|
||||
LL | | let _x: &'static i32 = &div_by_zero1();
|
||||
... |
|
||||
LL | | let _x: &'static i32 = &oob();
|
||||
LL | | };
|
||||
| |__-
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/promoted_errors.rs:9:9
|
||||
|
@ -40,41 +35,18 @@ note: the lint level is defined here
|
|||
LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: erroneous constant used
|
||||
--> $DIR/promoted_errors.rs:16:20
|
||||
warning: any use of this value will cause an error
|
||||
--> $DIR/promoted_errors.rs:31:28
|
||||
|
|
||||
LL | println!("{}", 1 / (1 - 1));
|
||||
| ^^^^^^^^^^^ referenced constant has errors
|
||||
LL | / const X: () = {
|
||||
LL | | let _x: &'static u32 = &overflow();
|
||||
| | ^^^^^^^^^^^ referenced constant has errors
|
||||
LL | |
|
||||
LL | | let _x: &'static i32 = &div_by_zero1();
|
||||
... |
|
||||
LL | | let _x: &'static i32 = &oob();
|
||||
LL | | };
|
||||
| |__-
|
||||
|
||||
warning: this operation will panic at runtime
|
||||
--> $DIR/promoted_errors.rs:20:14
|
||||
|
|
||||
LL | let _x = 1 / (1 - 1);
|
||||
| ^^^^^^^^^^^ attempt to divide `1_i32` by zero
|
||||
|
||||
warning: this operation will panic at runtime
|
||||
--> $DIR/promoted_errors.rs:22:20
|
||||
|
|
||||
LL | println!("{}", 1 / (false as u32));
|
||||
| ^^^^^^^^^^^^^^^^^^ attempt to divide `1_u32` by zero
|
||||
|
||||
warning: reaching this expression at runtime will panic or abort
|
||||
--> $DIR/promoted_errors.rs:22:20
|
||||
|
|
||||
LL | println!("{}", 1 / (false as u32));
|
||||
| ^^^^^^^^^^^^^^^^^^ dividing by zero
|
||||
|
||||
warning: erroneous constant used
|
||||
--> $DIR/promoted_errors.rs:22:20
|
||||
|
|
||||
LL | println!("{}", 1 / (false as u32));
|
||||
| ^^^^^^^^^^^^^^^^^^ referenced constant has errors
|
||||
|
||||
warning: this operation will panic at runtime
|
||||
--> $DIR/promoted_errors.rs:26:14
|
||||
|
|
||||
LL | let _x = 1 / (false as u32);
|
||||
| ^^^^^^^^^^^^^^^^^^ attempt to divide `1_u32` by zero
|
||||
|
||||
warning: 10 warnings emitted
|
||||
warning: 3 warnings emitted
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
warning: this arithmetic operation will overflow
|
||||
--> $DIR/promoted_errors.rs:14:14
|
||||
--> $DIR/promoted_errors.rs:13:5
|
||||
|
|
||||
LL | let _x = 0u32 - 1;
|
||||
| ^^^^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
|
||||
LL | 0 - 1
|
||||
| ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/promoted_errors.rs:9:20
|
||||
|
@ -11,10 +11,10 @@ LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
|
|||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: this operation will panic at runtime
|
||||
--> $DIR/promoted_errors.rs:16:20
|
||||
--> $DIR/promoted_errors.rs:17:5
|
||||
|
|
||||
LL | println!("{}", 1 / (1 - 1));
|
||||
| ^^^^^^^^^^^ attempt to divide `1_i32` by zero
|
||||
LL | 1 / 0
|
||||
| ^^^^^ attempt to divide `1_i32` by zero
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/promoted_errors.rs:9:41
|
||||
|
@ -22,11 +22,24 @@ note: the lint level is defined here
|
|||
LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: reaching this expression at runtime will panic or abort
|
||||
--> $DIR/promoted_errors.rs:16:20
|
||||
warning: any use of this value will cause an error
|
||||
--> $DIR/promoted_errors.rs:17:5
|
||||
|
|
||||
LL | println!("{}", 1 / (1 - 1));
|
||||
| ^^^^^^^^^^^ dividing by zero
|
||||
LL | 1 / 0
|
||||
| ^^^^^
|
||||
| |
|
||||
| attempt to divide `1_i32` by zero
|
||||
| inside `div_by_zero1` at $DIR/promoted_errors.rs:17:5
|
||||
| inside `X` at $DIR/promoted_errors.rs:33:29
|
||||
...
|
||||
LL | / const X: () = {
|
||||
LL | | let _x: &'static u32 = &overflow();
|
||||
LL | |
|
||||
LL | | let _x: &'static i32 = &div_by_zero1();
|
||||
... |
|
||||
LL | | let _x: &'static i32 = &oob();
|
||||
LL | | };
|
||||
| |__-
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/promoted_errors.rs:9:9
|
||||
|
@ -34,41 +47,18 @@ note: the lint level is defined here
|
|||
LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: erroneous constant used
|
||||
--> $DIR/promoted_errors.rs:16:20
|
||||
warning: any use of this value will cause an error
|
||||
--> $DIR/promoted_errors.rs:33:28
|
||||
|
|
||||
LL | println!("{}", 1 / (1 - 1));
|
||||
| ^^^^^^^^^^^ referenced constant has errors
|
||||
LL | / const X: () = {
|
||||
LL | | let _x: &'static u32 = &overflow();
|
||||
LL | |
|
||||
LL | | let _x: &'static i32 = &div_by_zero1();
|
||||
| | ^^^^^^^^^^^^^^^ referenced constant has errors
|
||||
... |
|
||||
LL | | let _x: &'static i32 = &oob();
|
||||
LL | | };
|
||||
| |__-
|
||||
|
||||
warning: this operation will panic at runtime
|
||||
--> $DIR/promoted_errors.rs:20:14
|
||||
|
|
||||
LL | let _x = 1 / (1 - 1);
|
||||
| ^^^^^^^^^^^ attempt to divide `1_i32` by zero
|
||||
|
||||
warning: this operation will panic at runtime
|
||||
--> $DIR/promoted_errors.rs:22:20
|
||||
|
|
||||
LL | println!("{}", 1 / (false as u32));
|
||||
| ^^^^^^^^^^^^^^^^^^ attempt to divide `1_u32` by zero
|
||||
|
||||
warning: reaching this expression at runtime will panic or abort
|
||||
--> $DIR/promoted_errors.rs:22:20
|
||||
|
|
||||
LL | println!("{}", 1 / (false as u32));
|
||||
| ^^^^^^^^^^^^^^^^^^ dividing by zero
|
||||
|
||||
warning: erroneous constant used
|
||||
--> $DIR/promoted_errors.rs:22:20
|
||||
|
|
||||
LL | println!("{}", 1 / (false as u32));
|
||||
| ^^^^^^^^^^^^^^^^^^ referenced constant has errors
|
||||
|
||||
warning: this operation will panic at runtime
|
||||
--> $DIR/promoted_errors.rs:26:14
|
||||
|
|
||||
LL | let _x = 1 / (false as u32);
|
||||
| ^^^^^^^^^^^^^^^^^^ attempt to divide `1_u32` by zero
|
||||
|
||||
warning: 9 warnings emitted
|
||||
warning: 4 warnings emitted
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
warning: this arithmetic operation will overflow
|
||||
--> $DIR/promoted_errors.rs:12:20
|
||||
--> $DIR/promoted_errors.rs:13:5
|
||||
|
|
||||
LL | println!("{}", 0u32 - 1);
|
||||
| ^^^^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
|
||||
LL | 0 - 1
|
||||
| ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/promoted_errors.rs:9:20
|
||||
|
@ -10,29 +10,24 @@ note: the lint level is defined here
|
|||
LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: this arithmetic operation will overflow
|
||||
--> $DIR/promoted_errors.rs:14:14
|
||||
warning: any use of this value will cause an error
|
||||
--> $DIR/promoted_errors.rs:13:5
|
||||
|
|
||||
LL | let _x = 0u32 - 1;
|
||||
| ^^^^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
|
||||
|
||||
warning: this operation will panic at runtime
|
||||
--> $DIR/promoted_errors.rs:16:20
|
||||
|
|
||||
LL | println!("{}", 1 / (1 - 1));
|
||||
| ^^^^^^^^^^^ attempt to divide `1_i32` by zero
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/promoted_errors.rs:9:41
|
||||
|
|
||||
LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: reaching this expression at runtime will panic or abort
|
||||
--> $DIR/promoted_errors.rs:16:20
|
||||
|
|
||||
LL | println!("{}", 1 / (1 - 1));
|
||||
| ^^^^^^^^^^^ dividing by zero
|
||||
LL | 0 - 1
|
||||
| ^^^^^
|
||||
| |
|
||||
| attempt to compute `0_u32 - 1_u32`, which would overflow
|
||||
| inside `overflow` at $DIR/promoted_errors.rs:13:5
|
||||
| inside `X` at $DIR/promoted_errors.rs:31:29
|
||||
...
|
||||
LL | / const X: () = {
|
||||
LL | | let _x: &'static u32 = &overflow();
|
||||
LL | |
|
||||
LL | | let _x: &'static i32 = &div_by_zero1();
|
||||
... |
|
||||
LL | | let _x: &'static i32 = &oob();
|
||||
LL | | };
|
||||
| |__-
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/promoted_errors.rs:9:9
|
||||
|
@ -40,41 +35,18 @@ note: the lint level is defined here
|
|||
LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: erroneous constant used
|
||||
--> $DIR/promoted_errors.rs:16:20
|
||||
warning: any use of this value will cause an error
|
||||
--> $DIR/promoted_errors.rs:31:28
|
||||
|
|
||||
LL | println!("{}", 1 / (1 - 1));
|
||||
| ^^^^^^^^^^^ referenced constant has errors
|
||||
LL | / const X: () = {
|
||||
LL | | let _x: &'static u32 = &overflow();
|
||||
| | ^^^^^^^^^^^ referenced constant has errors
|
||||
LL | |
|
||||
LL | | let _x: &'static i32 = &div_by_zero1();
|
||||
... |
|
||||
LL | | let _x: &'static i32 = &oob();
|
||||
LL | | };
|
||||
| |__-
|
||||
|
||||
warning: this operation will panic at runtime
|
||||
--> $DIR/promoted_errors.rs:20:14
|
||||
|
|
||||
LL | let _x = 1 / (1 - 1);
|
||||
| ^^^^^^^^^^^ attempt to divide `1_i32` by zero
|
||||
|
||||
warning: this operation will panic at runtime
|
||||
--> $DIR/promoted_errors.rs:22:20
|
||||
|
|
||||
LL | println!("{}", 1 / (false as u32));
|
||||
| ^^^^^^^^^^^^^^^^^^ attempt to divide `1_u32` by zero
|
||||
|
||||
warning: reaching this expression at runtime will panic or abort
|
||||
--> $DIR/promoted_errors.rs:22:20
|
||||
|
|
||||
LL | println!("{}", 1 / (false as u32));
|
||||
| ^^^^^^^^^^^^^^^^^^ dividing by zero
|
||||
|
||||
warning: erroneous constant used
|
||||
--> $DIR/promoted_errors.rs:22:20
|
||||
|
|
||||
LL | println!("{}", 1 / (false as u32));
|
||||
| ^^^^^^^^^^^^^^^^^^ referenced constant has errors
|
||||
|
||||
warning: this operation will panic at runtime
|
||||
--> $DIR/promoted_errors.rs:26:14
|
||||
|
|
||||
LL | let _x = 1 / (false as u32);
|
||||
| ^^^^^^^^^^^^^^^^^^ attempt to divide `1_u32` by zero
|
||||
|
||||
warning: 10 warnings emitted
|
||||
warning: 3 warnings emitted
|
||||
|
||||
|
|
|
@ -8,21 +8,34 @@
|
|||
|
||||
#![warn(const_err, arithmetic_overflow, unconditional_panic)]
|
||||
|
||||
fn main() {
|
||||
println!("{}", 0u32 - 1);
|
||||
//[opt_with_overflow_checks,noopt]~^ WARN [arithmetic_overflow]
|
||||
let _x = 0u32 - 1;
|
||||
//~^ WARN [arithmetic_overflow]
|
||||
println!("{}", 1 / (1 - 1));
|
||||
//~^ WARN [unconditional_panic]
|
||||
//~| WARN panic or abort [const_err]
|
||||
//~| WARN erroneous constant used [const_err]
|
||||
let _x = 1 / (1 - 1);
|
||||
//~^ WARN [unconditional_panic]
|
||||
println!("{}", 1 / (false as u32));
|
||||
//~^ WARN [unconditional_panic]
|
||||
//~| WARN panic or abort [const_err]
|
||||
//~| WARN erroneous constant used [const_err]
|
||||
let _x = 1 / (false as u32);
|
||||
//~^ WARN [unconditional_panic]
|
||||
// The only way to have promoteds that fail is in `const fn` called from `const`/`static`.
|
||||
const fn overflow() -> u32 {
|
||||
0 - 1 //~WARN arithmetic_overflow
|
||||
//[opt_with_overflow_checks,noopt]~^ WARN any use of this value will cause an error
|
||||
}
|
||||
const fn div_by_zero1() -> i32 {
|
||||
1 / 0 //[opt]~WARN unconditional_panic
|
||||
//[opt]~^ WARN any use of this value will cause an error
|
||||
}
|
||||
const fn div_by_zero2() -> i32 {
|
||||
1 / (1-1)
|
||||
}
|
||||
const fn div_by_zero3() -> i32 {
|
||||
1 / (false as i32)
|
||||
}
|
||||
const fn oob() -> i32 {
|
||||
[1,2,3][4]
|
||||
}
|
||||
|
||||
const X: () = {
|
||||
let _x: &'static u32 = &overflow();
|
||||
//[opt_with_overflow_checks,noopt]~^ WARN any use of this value will cause an error
|
||||
let _x: &'static i32 = &div_by_zero1();
|
||||
//[opt]~^ WARN any use of this value will cause an error
|
||||
let _x: &'static i32 = &div_by_zero2();
|
||||
let _x: &'static i32 = &div_by_zero3();
|
||||
let _x: &'static i32 = &oob();
|
||||
};
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
|
@ -44,4 +44,11 @@ fn main() {
|
|||
// We must not promote things with interior mutability. Not even if we "project it away".
|
||||
let _val: &'static _ = &(Cell::new(1), 2).0; //~ ERROR temporary value dropped while borrowed
|
||||
let _val: &'static _ = &(Cell::new(1), 2).1; //~ ERROR temporary value dropped while borrowed
|
||||
|
||||
// No promotion of fallible operations.
|
||||
let _val: &'static _ = &(1/0); //~ ERROR temporary value dropped while borrowed
|
||||
let _val: &'static _ = &(1/(1-1)); //~ ERROR temporary value dropped while borrowed
|
||||
let _val: &'static _ = &(1%0); //~ ERROR temporary value dropped while borrowed
|
||||
let _val: &'static _ = &(1%(1-1)); //~ ERROR temporary value dropped while borrowed
|
||||
let _val: &'static _ = &([1,2,3][4]+1); //~ ERROR temporary value dropped while borrowed
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ LL | let _val: &'static _ = &(Cell::new(1), 2).0;
|
|||
| ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
|
||||
| |
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
LL | let _val: &'static _ = &(Cell::new(1), 2).1;
|
||||
...
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
|
@ -76,9 +76,64 @@ LL | let _val: &'static _ = &(Cell::new(1), 2).1;
|
|||
| ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
|
||||
| |
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
...
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promote-not.rs:49:29
|
||||
|
|
||||
LL | let _val: &'static _ = &(1/0);
|
||||
| ---------- ^^^^^ creates a temporary which is freed while still in use
|
||||
| |
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
...
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promote-not.rs:50:29
|
||||
|
|
||||
LL | let _val: &'static _ = &(1/(1-1));
|
||||
| ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
|
||||
| |
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
...
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promote-not.rs:51:29
|
||||
|
|
||||
LL | let _val: &'static _ = &(1%0);
|
||||
| ---------- ^^^^^ creates a temporary which is freed while still in use
|
||||
| |
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
...
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promote-not.rs:52:29
|
||||
|
|
||||
LL | let _val: &'static _ = &(1%(1-1));
|
||||
| ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
|
||||
| |
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
LL | let _val: &'static _ = &([1,2,3][4]+1);
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promote-not.rs:53:29
|
||||
|
|
||||
LL | let _val: &'static _ = &([1,2,3][4]+1);
|
||||
| ---------- ^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
|
||||
| |
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0716`.
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
#![allow(unconditional_panic, const_err)]
|
||||
|
||||
// run-fail
|
||||
// error-pattern: attempt to divide by zero
|
||||
// ignore-emscripten no processes
|
||||
|
||||
fn main() {
|
||||
let x = &(1 / (1 - 1));
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// check-pass
|
||||
// run-pass
|
||||
|
||||
// compile-flags: -O
|
||||
|
||||
|
@ -25,4 +25,14 @@ fn main() {
|
|||
// make sure that these do not cause trouble despite overflowing
|
||||
baz_u32(&(0-1));
|
||||
baz_i32(&-i32::MIN);
|
||||
|
||||
// div-by-non-0 is okay
|
||||
baz_i32(&(1/1));
|
||||
baz_i32(&(1%1));
|
||||
|
||||
// Top-level projections do not get promoted, so no error here.
|
||||
if false {
|
||||
#[allow(unconditional_panic)]
|
||||
baz_i32(&[1,2,3][4]);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue