public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Fix bad transmute for aggregate types
@ 2022-08-06 12:10 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-08-06 12:10 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:7022b9dd107e534896d8383f6bc4ce70b4726cc9

commit 7022b9dd107e534896d8383f6bc4ce70b4726cc9
Author: Philip Herron <philip.herron@embecosm.com>
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<T>(a: T, b: T) -> T;
+        pub fn rotate_left<T>(a: T, b: T) -> T;
+        pub fn rotate_right<T>(a: T, b: T) -> T;
+        pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
+    }
+}
+
+mod mem {
+    extern "rust-intrinsic" {
+        fn transmute<T, U>(_: T) -> U;
+        fn size_of<T>() -> 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 {
+                    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>()]) -> Self {
+                    unsafe { mem::transmute(bytes) }
+                }
+            }
+        )*
+    }
+}
+
+impl_uint!(
+    u8 = "u8",
+    u16 = "u16",
+    u32 = "u32",
+    u64 = "u64",
+    u128 = "u128",
+    usize = "usize"
+);


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-08-06 12:10 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-06 12:10 [gcc/devel/rust/master] Fix bad transmute for aggregate types Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).