aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2021-08-16 18:44:47 +0200
committerMarc <dkm@kataplop.net>2021-08-18 22:59:35 +0200
commiteb5e504ec28bff08795c7a3aa541a555208e2517 (patch)
treedc24c1684e1bb2155729e50fdcf2a315922f0024 /gcc
parentd9082b50a98168b766cfc5136f50a3497c14897d (diff)
downloadgcc-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.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 (); } }
+}