Rollup merge of #74221 - oli-obk:const_prop_ice, r=wesleywiser

Don't panic if the lhs of a div by zero is not statically known

Fixes #73993 for real this time

r? @wesleywiser
This commit is contained in:
Manish Goregaokar 2020-07-16 11:18:50 -07:00 committed by GitHub
commit a80559f472
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 9 deletions

View File

@ -484,7 +484,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
lint: &'static lint::Lint,
source_info: SourceInfo,
message: &'static str,
panic: AssertKind<ConstInt>,
panic: AssertKind<impl std::fmt::Debug>,
) -> Option<()> {
let lint_root = self.lint_root(source_info)?;
self.tcx.struct_span_lint_hir(lint, lint_root, source_info.span, |lint| {
@ -1004,11 +1004,27 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
let expected = ScalarMaybeUninit::from(Scalar::from_bool(*expected));
let value_const = self.ecx.read_scalar(value).unwrap();
if expected != value_const {
enum DbgVal<T> {
Val(T),
Underscore,
}
impl<T: std::fmt::Debug> std::fmt::Debug for DbgVal<T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Val(val) => val.fmt(fmt),
Self::Underscore => fmt.write_str("_"),
}
}
}
let mut eval_to_int = |op| {
let op = self
.eval_operand(op, source_info)
.expect("if we got here, it must be const");
self.ecx.read_immediate(op).unwrap().to_const_int()
// This can be `None` if the lhs wasn't const propagated and we just
// triggered the assert on the value of the rhs.
match self.eval_operand(op, source_info) {
Some(op) => {
DbgVal::Val(self.ecx.read_immediate(op).unwrap().to_const_int())
}
None => DbgVal::Underscore,
}
};
let msg = match msg {
AssertKind::DivisionByZero(op) => {

View File

@ -1,9 +1,12 @@
// check-pass
// compile-flags: --crate-type lib
#![warn(unconditional_panic)]
pub struct Fixed64(i64);
pub fn div(f: Fixed64) {
f.0 / 0;
// HACK: this test passes only because this is a const fn that is written to metadata
pub const fn div(f: Fixed64) {
f.0 / 0; //~ WARN will panic at runtime
}
fn main() {}

View File

@ -0,0 +1,14 @@
warning: this operation will panic at runtime
--> $DIR/ice-assert-fail-div-by-zero.rs:11:5
|
LL | f.0 / 0;
| ^^^^^^^ attempt to divide _ by zero
|
note: the lint level is defined here
--> $DIR/ice-assert-fail-div-by-zero.rs:5:9
|
LL | #![warn(unconditional_panic)]
| ^^^^^^^^^^^^^^^^^^^
warning: 1 warning emitted