From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gnu.wildebeest.org (wildebeest.demon.nl [212.238.236.112]) by sourceware.org (Postfix) with ESMTPS id E0EC33951C9F for ; Mon, 16 Aug 2021 16:51:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E0EC33951C9F Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from reform (unknown [172.31.128.41]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 35B44302FBB1; Mon, 16 Aug 2021 18:51:35 +0200 (CEST) Received: by reform (Postfix, from userid 1000) id 333D42E83135; Mon, 16 Aug 2021 18:51:35 +0200 (CEST) From: Mark Wielaard To: gcc-rust@gcc.gnu.org Cc: Mark Wielaard Subject: [PATCH] Allow bool and char to be cast as any integer type Date: Mon, 16 Aug 2021 18:51:23 +0200 Message-Id: <20210816165123.48256-1-mark@klomp.org> X-Mailer: git-send-email 2.32.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-rust@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: gcc-rust mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Aug 2021 16:51:46 -0000 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 --- gcc/rust/typecheck/rust-tyty-cast.h | 12 +++++++ .../rust/compile/bad_as_bool_char.rs | 18 ++++++++++ .../rust/compile/torture/as_bool_char.rs | 36 +++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 gcc/testsuite/rust/compile/bad_as_bool_char.rs create mode 100644 gcc/testsuite/rust/compile/torture/as_bool_char.rs diff --git a/gcc/rust/typecheck/rust-tyty-cast.h b/gcc/rust/typecheck/rust-tyty-cast.h index de59b327e76..c457931b17f 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 00000000000..91a28eebe00 --- /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 00000000000..d687499384a --- /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 (); } } +} -- 2.32.0