aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-08-17 15:24:24 +0000
committerGitHub <noreply@github.com>2021-08-17 15:24:24 +0000
commit335cd53ddadbe43f2a1c2187fcbd28cf04fe911e (patch)
treedc24c1684e1bb2155729e50fdcf2a315922f0024 /gcc
parentd9082b50a98168b766cfc5136f50a3497c14897d (diff)
parent4f02b38f6ab17a49d9f6a681b1fefb89c12304d9 (diff)
downloadgcc-335cd53ddadbe43f2a1c2187fcbd28cf04fe911e.zip
gcc-335cd53ddadbe43f2a1c2187fcbd28cf04fe911e.tar.gz
gcc-335cd53ddadbe43f2a1c2187fcbd28cf04fe911e.tar.bz2
Merge #633
633: Allow bool and char to be cast as any integer type r=philberty a=dkm From Mark Wielaard : https://gcc.gnu.org/pipermail/gcc-rust/2021-August/000147.html > 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 Co-authored-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/typecheck/rust-tyty-cast.h12
-rw-r--r--gcc/testsuite/rust/compile/bad_as_bool_char.rs18
-rw-r--r--gcc/testsuite/rust/compile/torture/as_bool_char.rs36
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 (); } }
+}