Skip to content
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

Don't lint numeric overflows in promoteds in release mode #50841

Merged
merged 3 commits into from
May 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/librustc_codegen_llvm/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,10 +407,10 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
.unwrap_or_else(|err| {
match constant.literal {
mir::Literal::Promoted { .. } => {
// don't report errors inside promoteds, just warnings.
// FIXME: generate a panic here
},
mir::Literal::Value { .. } => {
err.report(bx.tcx(), constant.span, "const operand")
err.report(bx.tcx(), constant.span, "const operand");
},
}
// We've errored, so we don't have to produce working code.
Expand Down
12 changes: 2 additions & 10 deletions src/librustc_mir/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,21 +522,13 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
BinaryOp(bin_op, ref left, ref right) => {
let left = self.eval_operand(left)?;
let right = self.eval_operand(right)?;
if self.intrinsic_overflowing(
self.intrinsic_overflowing(
bin_op,
left,
right,
dest,
dest_ty,
)?
{
// There was an overflow in an unchecked binop. Right now, we consider this an error and bail out.
// The rationale is that the reason rustc emits unchecked binops in release mode (vs. the checked binops
// it emits in debug mode) is performance, but it doesn't cost us any performance in miri.
// If, however, the compiler ever starts transforming unchecked intrinsics into unchecked binops,
// we have to go back to just ignoring the overflow here.
return err!(Overflow(bin_op));
}
)?;
}

CheckedBinaryOp(bin_op, ref left, ref right) => {
Expand Down
17 changes: 17 additions & 0 deletions src/test/run-fail/promoted_div_by_zero.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(const_err)]

// error-pattern: attempt to divide by zero

fn main() {
let x = &(1 / (1 - 1));
}
18 changes: 18 additions & 0 deletions src/test/run-fail/promoted_overflow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(const_err)]

// error-pattern: overflow
// compile-flags: -C overflow-checks=yes

fn main() {
let x: &'static u32 = &(0u32 - 1);
}
18 changes: 18 additions & 0 deletions src/test/run-pass/promoted_overflow_opt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(const_err)]

// compile-flags: -O

fn main() {
let x = &(0u32 - 1);
assert_eq!(*x, u32::max_value())
}
38 changes: 38 additions & 0 deletions src/test/ui/const-eval/promoted_const_fn_fail.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(const_fn)]

#![deny(const_err)]

union Bar {
a: &'static u8,
b: usize,
}

const fn bar() -> u8 {
unsafe {
// this will error as long as this test
// is run on a system whose pointers need more
// than 8 bits
Bar { a: &42 }.b as u8
//~^ constant evaluation error
//~| constant evaluation error
}
}

fn main() {
// FIXME(oli-obk): this should compile but panic at runtime
// if we change the `const_err` lint to allow this will actually compile, but then
// continue with undefined values.
let x: &'static u8 = &(bar() + 1);
let y = *x;
unreachable!();
}
31 changes: 31 additions & 0 deletions src/test/ui/const-eval/promoted_const_fn_fail.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
error: constant evaluation error
--> $DIR/promoted_const_fn_fail.rs:25:9
|
LL | Bar { a: &42 }.b as u8
| ^^^^^^^^^^^^^^^^^^^^^^ a raw memory access tried to access part of a pointer value as raw bytes
|
note: lint level defined here
--> $DIR/promoted_const_fn_fail.rs:13:9
|
LL | #![deny(const_err)]
| ^^^^^^^^^
note: inside call to `bar`
--> $DIR/promoted_const_fn_fail.rs:35:28
|
LL | let x: &'static u8 = &(bar() + 1);
| ^^^^^

error: constant evaluation error
--> $DIR/promoted_const_fn_fail.rs:25:9
|
LL | Bar { a: &42 }.b as u8
| ^^^^^^^^^^^^^^^^^^^^^^ a raw memory access tried to access part of a pointer value as raw bytes
|
note: inside call to `bar`
--> $DIR/promoted_const_fn_fail.rs:35:28
|
LL | let x: &'static u8 = &(bar() + 1);
| ^^^^^

error: aborting due to 2 previous errors

2 changes: 0 additions & 2 deletions src/test/ui/const-eval/promoted_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
// compile-flags: -O
fn main() {
println!("{}", 0u32 - 1);
//~^ WARN const_err
//~| WARN const_err
let _x = 0u32 - 1;
//~^ WARN const_err
println!("{}", 1/(1-1));
Expand Down
28 changes: 8 additions & 20 deletions src/test/ui/const-eval/promoted_errors.stderr
Original file line number Diff line number Diff line change
@@ -1,53 +1,41 @@
warning: constant evaluation error
--> $DIR/promoted_errors.rs:16:20
--> $DIR/promoted_errors.rs:17:14
|
LL | println!("{}", 0u32 - 1);
| ^^^^^^^^ attempt to subtract with overflow
LL | let _x = 0u32 - 1;
| ^^^^^^^^ attempt to subtract with overflow
|
note: lint level defined here
--> $DIR/promoted_errors.rs:11:9
|
LL | #![warn(const_err)]
| ^^^^^^^^^

warning: constant evaluation error
--> $DIR/promoted_errors.rs:16:20
|
LL | println!("{}", 0u32 - 1);
| ^^^^^^^^ attempt to subtract with overflow

warning: constant evaluation error
--> $DIR/promoted_errors.rs:19:14
|
LL | let _x = 0u32 - 1;
| ^^^^^^^^ attempt to subtract with overflow

warning: attempt to divide by zero
--> $DIR/promoted_errors.rs:21:20
--> $DIR/promoted_errors.rs:19:20
|
LL | println!("{}", 1/(1-1));
| ^^^^^^^

warning: constant evaluation error
--> $DIR/promoted_errors.rs:21:20
--> $DIR/promoted_errors.rs:19:20
|
LL | println!("{}", 1/(1-1));
| ^^^^^^^ attempt to divide by zero

warning: attempt to divide by zero
--> $DIR/promoted_errors.rs:24:14
--> $DIR/promoted_errors.rs:22:14
|
LL | let _x = 1/(1-1);
| ^^^^^^^

warning: constant evaluation error
--> $DIR/promoted_errors.rs:24:14
--> $DIR/promoted_errors.rs:22:14
|
LL | let _x = 1/(1-1);
| ^^^^^^^ attempt to divide by zero

warning: constant evaluation error
--> $DIR/promoted_errors.rs:27:20
--> $DIR/promoted_errors.rs:25:20
|
LL | println!("{}", 1/(false as u32));
| ^^^^^^^^^^^^^^^^ attempt to divide by zero
Expand Down