rollup merge of #23863: pnkfelix/arith-oflo-const-eval
const_eval : add overflow-checking for {`+`, `-`, `*`, `/`, `<<`, `>>`}.
One tricky detail here: There is some duplication of labor between `rustc::middle::const_eval` and `rustc_trans::trans::consts`. It might be good to explore ways to try to factor out the common structure to the two passes (by abstracting over the particular value-representation used in the compile-time interpreter).
----
Update: Rebased atop #23841
Fix #22531
Fix #23030
Fix #23221
Fix #23235
This commit is contained in:
commit
4f643d79fc
30 changed files with 1733 additions and 267 deletions
30
src/test/compile-fail/const-eval-overflow-2.rs
Normal file
30
src/test/compile-fail/const-eval-overflow-2.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// Evaluation of constants in refutable patterns goes through
|
||||
// different compiler control-flow paths.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use std::fmt;
|
||||
use std::{i8, i16, i32, i64, isize};
|
||||
use std::{u8, u16, u32, u64, usize};
|
||||
|
||||
const NEG_128: i8 = -128;
|
||||
const NEG_NEG_128: i8 = -NEG_128;
|
||||
//~^ ERROR constant evaluation error: attempted to negate with overflow
|
||||
//~| ERROR attempted to negate with overflow
|
||||
|
||||
fn main() {
|
||||
match -128i8 {
|
||||
NEG_NEG_128 => println!("A"),
|
||||
_ => println!("B"),
|
||||
}
|
||||
}
|
||||
39
src/test/compile-fail/const-eval-overflow-3.rs
Normal file
39
src/test/compile-fail/const-eval-overflow-3.rs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// Evaluation of constants in array-elem count goes through different
|
||||
// compiler control-flow paths.
|
||||
//
|
||||
// This test is checking the count in an array expression.
|
||||
|
||||
// FIXME (#23926): the error output is not consistent between a
|
||||
// self-hosted and a cross-compiled setup; therefore resorting to
|
||||
// error-pattern for now.
|
||||
|
||||
// error-pattern: expected constant integer for repeat count, but attempted to add with overflow
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use std::fmt;
|
||||
use std::{i8, i16, i32, i64, isize};
|
||||
use std::{u8, u16, u32, u64, usize};
|
||||
|
||||
const A_I8_I
|
||||
: [u32; (i8::MAX as usize) + 1]
|
||||
= [0; (i8::MAX + 1) as usize];
|
||||
|
||||
fn main() {
|
||||
foo(&A_I8_I[..]);
|
||||
}
|
||||
|
||||
fn foo<T:fmt::Debug>(x: T) {
|
||||
println!("{:?}", x);
|
||||
}
|
||||
|
||||
43
src/test/compile-fail/const-eval-overflow-3b.rs
Normal file
43
src/test/compile-fail/const-eval-overflow-3b.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// Evaluation of constants in array-elem count goes through different
|
||||
// compiler control-flow paths.
|
||||
//
|
||||
// This test is checking the count in an array expression.
|
||||
//
|
||||
// This is a variation of another such test, but in this case the
|
||||
// types for the left- and right-hand sides of the addition do not
|
||||
// match (as well as overflow).
|
||||
|
||||
// FIXME (#23926): the error output is not consistent between a
|
||||
// self-hosted and a cross-compiled setup; therefore resorting to
|
||||
// error-pattern for now.
|
||||
|
||||
// error-pattern: mismatched types
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use std::fmt;
|
||||
use std::{i8, i16, i32, i64, isize};
|
||||
use std::{u8, u16, u32, u64, usize};
|
||||
|
||||
const A_I8_I
|
||||
: [u32; (i8::MAX as usize) + 1]
|
||||
= [0; (i8::MAX + 1u8) as usize];
|
||||
|
||||
fn main() {
|
||||
foo(&A_I8_I[..]);
|
||||
}
|
||||
|
||||
fn foo<T:fmt::Debug>(x: T) {
|
||||
println!("{:?}", x);
|
||||
}
|
||||
|
||||
36
src/test/compile-fail/const-eval-overflow-4.rs
Normal file
36
src/test/compile-fail/const-eval-overflow-4.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// ignore-test this should fail to compile (#23833)
|
||||
|
||||
// Evaluation of constants in array-elem count goes through different
|
||||
// compiler control-flow paths.
|
||||
//
|
||||
// This test is checking the count in an array type.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use std::fmt;
|
||||
use std::{i8, i16, i32, i64, isize};
|
||||
use std::{u8, u16, u32, u64, usize};
|
||||
|
||||
const A_I8_T
|
||||
: [u32; (i8::MAX as i8 + 1i8) as usize]
|
||||
//~^ ERROR error evaluating count: attempted to add with overflow
|
||||
= [0; (i8::MAX as usize) + 1];
|
||||
|
||||
fn main() {
|
||||
foo(&A_I8_T[..]);
|
||||
}
|
||||
|
||||
fn foo<T:fmt::Debug>(x: T) {
|
||||
println!("{:?}", x);
|
||||
}
|
||||
|
||||
36
src/test/compile-fail/const-eval-overflow-4b.rs
Normal file
36
src/test/compile-fail/const-eval-overflow-4b.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// Evaluation of constants in array-elem count goes through different
|
||||
// compiler control-flow paths.
|
||||
//
|
||||
// This test is checking the count in an array type.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use std::fmt;
|
||||
use std::{i8, i16, i32, i64, isize};
|
||||
use std::{u8, u16, u32, u64, usize};
|
||||
|
||||
const A_I8_T
|
||||
: [u32; (i8::MAX as i8 + 1u8) as usize]
|
||||
//~^ ERROR mismatched types
|
||||
//~| the trait `core::ops::Add<u8>` is not implemented for the type `i8`
|
||||
//~| the trait `core::ops::Add<u8>` is not implemented for the type `i8`
|
||||
= [0; (i8::MAX as usize) + 1];
|
||||
|
||||
fn main() {
|
||||
foo(&A_I8_T[..]);
|
||||
}
|
||||
|
||||
fn foo<T:fmt::Debug>(x: T) {
|
||||
println!("{:?}", x);
|
||||
}
|
||||
|
||||
129
src/test/compile-fail/const-eval-overflow.rs
Normal file
129
src/test/compile-fail/const-eval-overflow.rs
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
// Copyright 2015 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(unused_imports)]
|
||||
|
||||
// Note: the relevant lint pass here runs before some of the constant
|
||||
// evaluation below (e.g. that performed by trans and llvm), so if you
|
||||
// change this warn to a deny, then the compiler will exit before
|
||||
// those errors are detected.
|
||||
#![warn(unsigned_negation)]
|
||||
|
||||
use std::fmt;
|
||||
use std::{i8, i16, i32, i64, isize};
|
||||
use std::{u8, u16, u32, u64, usize};
|
||||
|
||||
const VALS_I8: (i8, i8, i8, i8) =
|
||||
(-i8::MIN,
|
||||
//~^ ERROR attempted to negate with overflow
|
||||
i8::MIN - 1,
|
||||
//~^ ERROR attempted to sub with overflow
|
||||
i8::MAX + 1,
|
||||
//~^ ERROR attempted to add with overflow
|
||||
i8::MIN * 2,
|
||||
//~^ ERROR attempted to mul with overflow
|
||||
);
|
||||
|
||||
const VALS_I16: (i16, i16, i16, i16) =
|
||||
(-i16::MIN,
|
||||
//~^ ERROR attempted to negate with overflow
|
||||
i16::MIN - 1,
|
||||
//~^ ERROR attempted to sub with overflow
|
||||
i16::MAX + 1,
|
||||
//~^ ERROR attempted to add with overflow
|
||||
i16::MIN * 2,
|
||||
//~^ ERROR attempted to mul with overflow
|
||||
);
|
||||
|
||||
const VALS_I32: (i32, i32, i32, i32) =
|
||||
(-i32::MIN,
|
||||
//~^ ERROR attempted to negate with overflow
|
||||
i32::MIN - 1,
|
||||
//~^ ERROR attempted to sub with overflow
|
||||
i32::MAX + 1,
|
||||
//~^ ERROR attempted to add with overflow
|
||||
i32::MIN * 2,
|
||||
//~^ ERROR attempted to mul with overflow
|
||||
);
|
||||
|
||||
const VALS_I64: (i64, i64, i64, i64) =
|
||||
(-i64::MIN,
|
||||
//~^ ERROR attempted to negate with overflow
|
||||
i64::MIN - 1,
|
||||
//~^ ERROR attempted to sub with overflow
|
||||
i64::MAX + 1,
|
||||
//~^ ERROR attempted to add with overflow
|
||||
i64::MAX * 2,
|
||||
//~^ ERROR attempted to mul with overflow
|
||||
);
|
||||
|
||||
const VALS_U8: (u8, u8, u8, u8) =
|
||||
(-u8::MIN,
|
||||
//~^ WARNING negation of unsigned int variable may be unintentional
|
||||
// (The above is separately linted; unsigned negation is defined to be !x+1.)
|
||||
u8::MIN - 1,
|
||||
//~^ ERROR attempted to sub with overflow
|
||||
u8::MAX + 1,
|
||||
//~^ ERROR attempted to add with overflow
|
||||
u8::MAX * 2,
|
||||
//~^ ERROR attempted to mul with overflow
|
||||
);
|
||||
|
||||
const VALS_U16: (u16, u16, u16, u16) =
|
||||
(-u16::MIN,
|
||||
//~^ WARNING negation of unsigned int variable may be unintentional
|
||||
// (The above is separately linted; unsigned negation is defined to be !x+1.)
|
||||
u16::MIN - 1,
|
||||
//~^ ERROR attempted to sub with overflow
|
||||
u16::MAX + 1,
|
||||
//~^ ERROR attempted to add with overflow
|
||||
u16::MAX * 2,
|
||||
//~^ ERROR attempted to mul with overflow
|
||||
);
|
||||
|
||||
const VALS_U32: (u32, u32, u32, u32) =
|
||||
(-u32::MIN,
|
||||
//~^ WARNING negation of unsigned int variable may be unintentional
|
||||
// (The above is separately linted; unsigned negation is defined to be !x+1.)
|
||||
u32::MIN - 1,
|
||||
//~^ ERROR attempted to sub with overflow
|
||||
u32::MAX + 1,
|
||||
//~^ ERROR attempted to add with overflow
|
||||
u32::MAX * 2,
|
||||
//~^ ERROR attempted to mul with overflow
|
||||
);
|
||||
|
||||
const VALS_U64: (u64, u64, u64, u64) =
|
||||
(-u64::MIN,
|
||||
//~^ WARNING negation of unsigned int variable may be unintentional
|
||||
// (The above is separately linted; unsigned negation is defined to be !x+1.)
|
||||
u64::MIN - 1,
|
||||
//~^ ERROR attempted to sub with overflow
|
||||
u64::MAX + 1,
|
||||
//~^ ERROR attempted to add with overflow
|
||||
u64::MAX * 2,
|
||||
//~^ ERROR attempted to mul with overflow
|
||||
);
|
||||
|
||||
fn main() {
|
||||
foo(VALS_I8);
|
||||
foo(VALS_I16);
|
||||
foo(VALS_I32);
|
||||
foo(VALS_I64);
|
||||
|
||||
foo(VALS_U8);
|
||||
foo(VALS_U16);
|
||||
foo(VALS_U32);
|
||||
foo(VALS_U64);
|
||||
}
|
||||
|
||||
fn foo<T:fmt::Debug>(x: T) {
|
||||
println!("{:?}", x);
|
||||
}
|
||||
118
src/test/compile-fail/discrim-ill-typed.rs
Normal file
118
src/test/compile-fail/discrim-ill-typed.rs
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// When explicit discriminant value has
|
||||
// a type that does not match the representation
|
||||
// type, rustc should fail gracefully.
|
||||
|
||||
// See also run-pass/discrim-explicit-23030.rs where the input types
|
||||
// are correct.
|
||||
|
||||
#![allow(dead_code, unused_variables, unused_imports)]
|
||||
|
||||
use std::{i8,u8,i16,u16,i32,u32,i64, u64};
|
||||
|
||||
fn f_i8() {
|
||||
#[repr(i8)]
|
||||
enum A {
|
||||
Ok = i8::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = 0_u8,
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_u8() {
|
||||
#[repr(u8)]
|
||||
enum A {
|
||||
Ok = u8::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = 0_i8,
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_i16() {
|
||||
#[repr(i16)]
|
||||
enum A {
|
||||
Ok = i16::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = 0_u16,
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_u16() {
|
||||
#[repr(u16)]
|
||||
enum A {
|
||||
Ok = u16::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = 0_i16,
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_i32() {
|
||||
#[repr(i32)]
|
||||
enum A {
|
||||
Ok = i32::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = 0_u32,
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_u32() {
|
||||
#[repr(u32)]
|
||||
enum A {
|
||||
Ok = u32::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = 0_i32,
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_i64() {
|
||||
#[repr(i64)]
|
||||
enum A {
|
||||
Ok = i64::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = 0_u64,
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_u64() {
|
||||
#[repr(u64)]
|
||||
enum A {
|
||||
Ok = u64::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = 0_i64,
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
94
src/test/compile-fail/discrim-overflow-2.rs
Normal file
94
src/test/compile-fail/discrim-overflow-2.rs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// ignore-tidy-linelength
|
||||
|
||||
// Issue 23030: Detect overflowing discriminant
|
||||
//
|
||||
// Check that we detect the overflow even if enum is not used.
|
||||
|
||||
// See also run-pass/discrim-explicit-23030.rs where the suggested
|
||||
// workaround is tested.
|
||||
|
||||
use std::{i8,u8,i16,u16,i32,u32,i64, u64};
|
||||
|
||||
fn f_i8() {
|
||||
#[repr(i8)]
|
||||
enum A {
|
||||
Ok = i8::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed on value after 127: i8; set explicitly via OhNo = -128 if that is desired outcome
|
||||
}
|
||||
}
|
||||
|
||||
fn f_u8() {
|
||||
#[repr(u8)]
|
||||
enum A {
|
||||
Ok = u8::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed on value after 255: u8; set explicitly via OhNo = 0 if that is desired outcome
|
||||
}
|
||||
}
|
||||
|
||||
fn f_i16() {
|
||||
#[repr(i16)]
|
||||
enum A {
|
||||
Ok = i16::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed
|
||||
}
|
||||
}
|
||||
|
||||
fn f_u16() {
|
||||
#[repr(u16)]
|
||||
enum A {
|
||||
Ok = u16::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed
|
||||
}
|
||||
}
|
||||
|
||||
fn f_i32() {
|
||||
#[repr(i32)]
|
||||
enum A {
|
||||
Ok = i32::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed
|
||||
}
|
||||
}
|
||||
|
||||
fn f_u32() {
|
||||
#[repr(u32)]
|
||||
enum A {
|
||||
Ok = u32::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed
|
||||
}
|
||||
}
|
||||
|
||||
fn f_i64() {
|
||||
#[repr(i64)]
|
||||
enum A {
|
||||
Ok = i64::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed
|
||||
}
|
||||
}
|
||||
|
||||
fn f_u64() {
|
||||
#[repr(u64)]
|
||||
enum A {
|
||||
Ok = u64::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
108
src/test/compile-fail/discrim-overflow.rs
Normal file
108
src/test/compile-fail/discrim-overflow.rs
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// ignore-tidy-linelength
|
||||
|
||||
// Issue 23030: Detect overflowing discriminant
|
||||
|
||||
// See also run-pass/discrim-explicit-23030.rs where the suggested
|
||||
// workaround is tested.
|
||||
|
||||
use std::{i8,u8,i16,u16,i32,u32,i64, u64};
|
||||
|
||||
fn f_i8() {
|
||||
#[repr(i8)]
|
||||
enum A {
|
||||
Ok = i8::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed on value after 127: i8; set explicitly via OhNo = -128 if that is desired outcome
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_u8() {
|
||||
#[repr(u8)]
|
||||
enum A {
|
||||
Ok = u8::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed on value after 255: u8; set explicitly via OhNo = 0 if that is desired outcome
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_i16() {
|
||||
#[repr(i16)]
|
||||
enum A {
|
||||
Ok = i16::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_u16() {
|
||||
#[repr(u16)]
|
||||
enum A {
|
||||
Ok = u16::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_i32() {
|
||||
#[repr(i32)]
|
||||
enum A {
|
||||
Ok = i32::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_u32() {
|
||||
#[repr(u32)]
|
||||
enum A {
|
||||
Ok = u32::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_i64() {
|
||||
#[repr(i64)]
|
||||
enum A {
|
||||
Ok = i64::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn f_u64() {
|
||||
#[repr(u64)]
|
||||
enum A {
|
||||
Ok = u64::MAX - 1,
|
||||
Ok2,
|
||||
OhNo, //~ ERROR enum discriminant overflowed
|
||||
}
|
||||
|
||||
let x = A::Ok;
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
@ -8,9 +8,14 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: too big for the current
|
||||
// FIXME (#23926): the error output is not consistent between a
|
||||
// self-hosted and a cross-compiled setup. Skipping for now.
|
||||
|
||||
// ignore-test FIXME(#23926)
|
||||
|
||||
#![allow(exceeding_bitshifts)]
|
||||
|
||||
fn main() {
|
||||
let fat : [u8; (1<<61)+(1<<31)] = [0; (1u64<<61) as usize +(1u64<<31) as usize];
|
||||
let _fat : [u8; (1<<61)+(1<<31)] =
|
||||
[0; (1u64<<61) as usize +(1u64<<31) as usize];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,12 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Note: This test is checking that we forbid a coding pattern that
|
||||
// Issue #5873 explicitly wants to allow.
|
||||
|
||||
enum State { ST_NULL, ST_WHITESPACE }
|
||||
|
||||
fn main() {
|
||||
[State::ST_NULL; (State::ST_WHITESPACE as usize)];
|
||||
//~^ ERROR expected constant integer for repeat count, found non-constant expression
|
||||
//~^ ERROR expected constant integer for repeat count, but non-constant path
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
fn main() {
|
||||
fn bar(n: usize) {
|
||||
let _x = [0; n]; //~ ERROR expected constant integer for repeat count, found variable
|
||||
let _x = [0; n];
|
||||
//~^ ERROR expected constant integer for repeat count, found variable
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,16 @@
|
|||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![feature(core)]
|
||||
|
||||
// Catch mistakes in the overflowing literals lint.
|
||||
#![deny(overflowing_literals)]
|
||||
|
||||
pub fn main() {
|
||||
assert_eq!(0xffffffff, (-1 as u32));
|
||||
assert_eq!(4294967295, (-1 as u32));
|
||||
assert_eq!(0xffffffffffffffff, (-1 as u64));
|
||||
assert_eq!(18446744073709551615, (-1 as u64));
|
||||
|
||||
assert_eq!(-2147483648 - 1, 2147483647);
|
||||
assert_eq!((-2147483648).wrapping_sub(1), 2147483647);
|
||||
}
|
||||
|
|
|
|||
156
src/test/run-pass/discrim-explicit-23030.rs
Normal file
156
src/test/run-pass/discrim-explicit-23030.rs
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// Issue 23030: Workaround overflowing discriminant
|
||||
// with explicit assignments.
|
||||
|
||||
// See also compile-fail/overflow-discrim.rs, which shows what
|
||||
// happens if you leave the OhNo explicit cases out here.
|
||||
|
||||
use std::{i8,u8,i16,u16,i32,u32,i64,u64,isize,usize};
|
||||
|
||||
fn f_i8() {
|
||||
#[repr(i8)]
|
||||
enum A {
|
||||
Ok = i8::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = i8::MIN,
|
||||
NotTheEnd = -1,
|
||||
Zero,
|
||||
}
|
||||
|
||||
let _x = (A::Ok, A::Ok2, A::OhNo);
|
||||
let z = (A::NotTheEnd, A::Zero).1 as i8;
|
||||
assert_eq!(z, 0);
|
||||
}
|
||||
|
||||
fn f_u8() {
|
||||
#[repr(u8)]
|
||||
enum A {
|
||||
Ok = u8::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = u8::MIN,
|
||||
}
|
||||
|
||||
let _x = (A::Ok, A::Ok2, A::OhNo);
|
||||
}
|
||||
|
||||
fn f_i16() {
|
||||
#[repr(i16)]
|
||||
enum A {
|
||||
Ok = i16::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = i16::MIN,
|
||||
NotTheEnd = -1,
|
||||
Zero,
|
||||
}
|
||||
|
||||
let _x = (A::Ok, A::Ok2, A::OhNo);
|
||||
let z = (A::NotTheEnd, A::Zero).1 as i16;
|
||||
assert_eq!(z, 0);
|
||||
}
|
||||
|
||||
fn f_u16() {
|
||||
#[repr(u16)]
|
||||
enum A {
|
||||
Ok = u16::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = u16::MIN,
|
||||
}
|
||||
|
||||
let _x = (A::Ok, A::Ok2, A::OhNo);
|
||||
}
|
||||
|
||||
fn f_i32() {
|
||||
#[repr(i32)]
|
||||
enum A {
|
||||
Ok = i32::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = i32::MIN,
|
||||
NotTheEnd = -1,
|
||||
Zero,
|
||||
}
|
||||
|
||||
let _x = (A::Ok, A::Ok2, A::OhNo);
|
||||
let z = (A::NotTheEnd, A::Zero).1 as i32;
|
||||
assert_eq!(z, 0);
|
||||
}
|
||||
|
||||
fn f_u32() {
|
||||
#[repr(u32)]
|
||||
enum A {
|
||||
Ok = u32::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = u32::MIN,
|
||||
}
|
||||
|
||||
let _x = (A::Ok, A::Ok2, A::OhNo);
|
||||
}
|
||||
|
||||
fn f_i64() {
|
||||
#[repr(i64)]
|
||||
enum A {
|
||||
Ok = i64::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = i64::MIN,
|
||||
NotTheEnd = -1,
|
||||
Zero,
|
||||
}
|
||||
|
||||
let _x = (A::Ok, A::Ok2, A::OhNo);
|
||||
let z = (A::NotTheEnd, A::Zero).1 as i64;
|
||||
assert_eq!(z, 0);
|
||||
}
|
||||
|
||||
fn f_u64() {
|
||||
#[repr(u64)]
|
||||
enum A {
|
||||
Ok = u64::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = u64::MIN,
|
||||
}
|
||||
|
||||
let _x = (A::Ok, A::Ok2, A::OhNo);
|
||||
}
|
||||
|
||||
fn f_isize() {
|
||||
#[repr(isize)]
|
||||
enum A {
|
||||
Ok = isize::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = isize::MIN,
|
||||
NotTheEnd = -1,
|
||||
Zero,
|
||||
}
|
||||
|
||||
let _x = (A::Ok, A::Ok2, A::OhNo);
|
||||
let z = (A::NotTheEnd, A::Zero).1 as isize;
|
||||
assert_eq!(z, 0);
|
||||
}
|
||||
|
||||
fn f_usize() {
|
||||
#[repr(usize)]
|
||||
enum A {
|
||||
Ok = usize::MAX - 1,
|
||||
Ok2,
|
||||
OhNo = usize::MIN,
|
||||
}
|
||||
|
||||
let _x = (A::Ok, A::Ok2, A::OhNo);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
f_i8(); f_u8();
|
||||
f_i16(); f_u16();
|
||||
f_i32(); f_u32();
|
||||
f_i64(); f_u64();
|
||||
|
||||
f_isize(); f_usize();
|
||||
}
|
||||
|
|
@ -10,6 +10,9 @@
|
|||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
// this is for the wrapping_add call below.
|
||||
#![feature(core)]
|
||||
|
||||
/*!
|
||||
* Tests the range assertion wraparound case in trans::middle::adt::load_discr.
|
||||
*/
|
||||
|
|
@ -29,8 +32,8 @@ static CLs: Es = Es::Ls;
|
|||
static CHs: Es = Es::Hs;
|
||||
|
||||
pub fn main() {
|
||||
assert_eq!((Eu::Hu as u8) + 1, Eu::Lu as u8);
|
||||
assert_eq!((Es::Hs as i8) + 1, Es::Ls as i8);
|
||||
assert_eq!((Eu::Hu as u8).wrapping_add(1), Eu::Lu as u8);
|
||||
assert_eq!((Es::Hs as i8).wrapping_add(1), Es::Ls as i8);
|
||||
assert_eq!(CLu as u8, Eu::Lu as u8);
|
||||
assert_eq!(CHu as u8, Eu::Hu as u8);
|
||||
assert_eq!(CLs as i8, Es::Ls as i8);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue