From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id EABD83858437; Sat, 6 Aug 2022 12:10:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EABD83858437 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Thomas Schwinge To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] Fix bad transmute for aggregate types X-Act-Checkin: gcc X-Git-Author: Philip Herron X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: c788a806195f326a595cd15b96c59e7584927f1a X-Git-Newrev: 7022b9dd107e534896d8383f6bc4ce70b4726cc9 Message-Id: <20220806121010.EABD83858437@sourceware.org> Date: Sat, 6 Aug 2022 12:10:10 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Aug 2022 12:10:11 -0000 https://gcc.gnu.org/g:7022b9dd107e534896d8383f6bc4ce70b4726cc9 commit 7022b9dd107e534896d8383f6bc4ce70b4726cc9 Author: Philip Herron Date: Thu Aug 4 20:25:59 2022 +0100 Fix bad transmute for aggregate types This changes the CONVERT_EXPR to use the same *(foo*)&bar style cast from the c front-end to handle the case of: int a[1]; int b = (int)a; Which is converted into: int b = *(int*)&a; which the constant folders can turn directly into int b = a[0]; Fixes #1432 Diff: --- gcc/rust/backend/rust-compile-intrinsic.cc | 18 +++++- gcc/testsuite/rust/compile/torture/issue-1432.rs | 72 ++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc index 65eddfac9ef..88d7923a50f 100644 --- a/gcc/rust/backend/rust-compile-intrinsic.cc +++ b/gcc/rust/backend/rust-compile-intrinsic.cc @@ -545,8 +545,22 @@ transmute_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty) tree result_expr = error_mark_node; if (AGGREGATE_TYPE_P (TREE_TYPE (convert_me_expr))) { - result_expr = fold_build1_loc (Location ().gcc_location (), CONVERT_EXPR, - result_type_tree, convert_me_expr); + // Return *(orig_type*)&decl. */ + // tree t = build_fold_addr_expr_loc (location.gcc_location (), this->t_); + // t = fold_build1_loc (location.gcc_location (), NOP_EXPR, + // build_pointer_type (this->orig_type_), t); + // return build_fold_indirect_ref_loc (location.gcc_location (), t); + + // result_expr = fold_build1_loc (Location ().gcc_location (), + // CONVERT_EXPR, + // result_type_tree, convert_me_expr); + + tree t = build_fold_addr_expr_loc (Location ().gcc_location (), + convert_me_expr); + t = fold_build1_loc (Location ().gcc_location (), NOP_EXPR, + build_pointer_type (target_type_expr), t); + result_expr + = build_fold_indirect_ref_loc (Location ().gcc_location (), t); } else { diff --git a/gcc/testsuite/rust/compile/torture/issue-1432.rs b/gcc/testsuite/rust/compile/torture/issue-1432.rs new file mode 100644 index 00000000000..2a238e14744 --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/issue-1432.rs @@ -0,0 +1,72 @@ +// { dg-additional-options "-w" } +mod intrinsics { + extern "rust-intrinsic" { + pub fn wrapping_add(a: T, b: T) -> T; + pub fn rotate_left(a: T, b: T) -> T; + pub fn rotate_right(a: T, b: T) -> T; + pub fn offset(ptr: *const T, count: isize) -> *const T; + } +} + +mod mem { + extern "rust-intrinsic" { + fn transmute(_: T) -> U; + fn size_of() -> usize; + } +} + +macro_rules! impl_uint { + ($($ty:ident = $lang:literal),*) => { + $( + impl $ty { + pub fn wrapping_add(self, rhs: Self) -> Self { + // intrinsics::wrapping_add(self, rhs) + self + rhs + } + + pub fn rotate_left(self, n: u32) -> Self { + unsafe { + intrinsics::rotate_left(self, n as Self) + } + } + + pub fn rotate_right(self, n: u32) -> Self { + unsafe { + intrinsics::rotate_right(self, n as Self) + } + } + + pub fn to_le(self) -> Self { + #[cfg(target_endian = "little")] + { + self + } + } + + pub const fn from_le_bytes(bytes: [u8; mem::size_of::()]) -> Self { + Self::from_le(Self::from_ne_bytes(bytes)) + } + + pub const fn from_le(x: Self) -> Self { + #[cfg(target_endian = "little")] + { + x + } + } + + pub const fn from_ne_bytes(bytes: [u8; mem::size_of::()]) -> Self { + unsafe { mem::transmute(bytes) } + } + } + )* + } +} + +impl_uint!( + u8 = "u8", + u16 = "u16", + u32 = "u32", + u64 = "u64", + u128 = "u128", + usize = "usize" +);