diff options
author | Mark Wielaard <mark@klomp.org> | 2021-08-16 18:44:47 +0200 |
---|---|---|
committer | Marc <dkm@kataplop.net> | 2021-08-18 22:59:35 +0200 |
commit | eb5e504ec28bff08795c7a3aa541a555208e2517 (patch) | |
tree | dc24c1684e1bb2155729e50fdcf2a315922f0024 /gcc | |
parent | d9082b50a98168b766cfc5136f50a3497c14897d (diff) | |
download | gcc-eb5e504ec28bff08795c7a3aa541a555208e2517.zip gcc-eb5e504ec28bff08795c7a3aa541a555208e2517.tar.gz gcc-eb5e504ec28bff08795c7a3aa541a555208e2517.tar.bz2 |
Allow bool and char to be cast as any integer type
bools and chars can be cast to any integer type, but not to floats or
each other. Adjust the BoolCastRule and CharCastRule to allow these
casts. Add a postive test "as_bool_char.rs" and negative test
"bad_as_bool_char.rs" to check the correct casts are accepted and the
illegal casts produce errors.
Resolves: https://github.com/Rust-GCC/gccrs/issues/629
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-cast.h | 12 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/bad_as_bool_char.rs | 18 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/as_bool_char.rs | 36 |
3 files changed, 66 insertions, 0 deletions
diff --git a/gcc/rust/typecheck/rust-tyty-cast.h b/gcc/rust/typecheck/rust-tyty-cast.h index de59b32..c457931 100644 --- a/gcc/rust/typecheck/rust-tyty-cast.h +++ b/gcc/rust/typecheck/rust-tyty-cast.h @@ -779,6 +779,12 @@ public: } } + /* bools can be cast to any integer type (but not floats or chars). */ + void visit (IntType &type) override { resolved = type.clone (); } + void visit (UintType &type) override { resolved = type.clone (); } + void visit (USizeType &type) override { resolved = type.clone (); } + void visit (ISizeType &type) override { resolved = type.clone (); } + private: BaseType *get_base () override { return base; } @@ -1078,6 +1084,12 @@ public: void visit (CharType &type) override { resolved = type.clone (); } + /* chars can be cast to any integer type (but not floats or bools). */ + void visit (IntType &type) override { resolved = type.clone (); } + void visit (UintType &type) override { resolved = type.clone (); } + void visit (USizeType &type) override { resolved = type.clone (); } + void visit (ISizeType &type) override { resolved = type.clone (); } + private: BaseType *get_base () override { return base; } diff --git a/gcc/testsuite/rust/compile/bad_as_bool_char.rs b/gcc/testsuite/rust/compile/bad_as_bool_char.rs new file mode 100644 index 0000000..91a28ee --- /dev/null +++ b/gcc/testsuite/rust/compile/bad_as_bool_char.rs @@ -0,0 +1,18 @@ +pub fn main () +{ + let t = true; + let f = false; + let fone = t as f32; // { dg-error "invalid cast" } + let fzero = f as f64; // { dg-error "invalid cast" } + + let nb = 0u8 as bool; // { dg-error "invalid cast" } + let nc = true as char; // { dg-error "invalid cast" } + + let a = 'a'; + let b = 'b'; + let fa = a as f32; // { dg-error "invalid cast" } + let bb = b as bool; // { dg-error "invalid cast" } + + let t32: u32 = 33; + let ab = t32 as char; // { dg-error "invalid cast" } +} diff --git a/gcc/testsuite/rust/compile/torture/as_bool_char.rs b/gcc/testsuite/rust/compile/torture/as_bool_char.rs new file mode 100644 index 0000000..d687499 --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/as_bool_char.rs @@ -0,0 +1,36 @@ +extern "C" { fn abort (); } + +pub fn main () +{ + let t = true; + let f = false; + let one = t as u8; + let zero = f as u8; + + if one != 1 || zero != 0 { unsafe { abort (); } } + + let isizeone = true as isize; + let usizezero = false as usize; + + if isizeone != 1 || usizezero != 0 { unsafe { abort (); } } + + let i32zero = f as i32; + let u128one = t as u128; + + if u128one != 1 || i32zero != 0 { unsafe { abort (); } } + + let a = 'a'; + let b = 'b'; + let ua = a as u8; + let ib = b as i32; + + if (ua + 1) as i32 != ib { unsafe { abort (); } } + + let tt = ua; + let aa = tt as char; + + let ttt = tt + 1; + let ab = ttt as char; + + if aa != 'a' || ab != 'b' { unsafe { abort (); } } +} |