public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] rust/intrinsic: add a basic size check for transmute
@ 2022-06-09  6:16 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-09  6:16 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:188dd73755914865bd138eb886094fb957ab185c

commit 188dd73755914865bd138eb886094fb957ab185c
Author: liushuyu <liushuyu011@gmail.com>
Date:   Mon Jun 6 18:49:42 2022 -0600

    rust/intrinsic: add a basic size check for transmute

Diff:
---
 gcc/rust/backend/rust-compile-intrinsic.cc         | 32 ++++++++++++++++++++++
 gcc/rust/hir/tree/rust-hir-type.h                  |  5 +---
 .../rust/compile/torture/transmute-size-check-1.rs | 11 ++++++++
 3 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index a7225f2ab05..e93480db134 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -20,6 +20,8 @@
 #include "rust-compile-context.h"
 #include "rust-compile-type.h"
 #include "rust-compile-fnparam.h"
+#include "rust-diagnostics.h"
+#include "rust-location.h"
 #include "rust-tree.h"
 #include "tree-core.h"
 
@@ -477,6 +479,7 @@ transmute_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
 
   // setup the params
   std::vector<Bvariable *> param_vars;
+  std::vector<tree_node *> compiled_types;
   for (auto &parm : fntype->get_params ())
     {
       auto &referenced_param = parm.first;
@@ -489,6 +492,7 @@ transmute_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
 				   compiled_param_type, param_locus);
 
       param_vars.push_back (compiled_param_var);
+      compiled_types.push_back (compiled_param_type);
     }
 
   rust_assert (param_vars.size () == 1);
@@ -500,6 +504,34 @@ transmute_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
   tree convert_me_expr
     = ctx->get_backend ()->var_expression (convert_me_param, Location ());
 
+  // check for transmute pre-conditions
+  tree target_type_expr = TREE_TYPE (DECL_RESULT (fndecl));
+  tree source_type_expr = compiled_types.at (0);
+  tree target_size_expr = TYPE_SIZE (target_type_expr);
+  tree source_size_expr = TYPE_SIZE (source_type_expr);
+  // for some reason, unit types and other zero-sized types return NULL for the
+  // size expressions
+  unsigned HOST_WIDE_INT target_size
+    = target_size_expr ? TREE_INT_CST_LOW (target_size_expr) : 0;
+  unsigned HOST_WIDE_INT source_size
+    = source_size_expr ? TREE_INT_CST_LOW (source_size_expr) : 0;
+
+  // size check for concrete types
+  // TODO(liushuyu): check alignment for pointers; check for dependently-sized
+  // types
+  if (target_size != source_size)
+    {
+      rust_error_at (fntype->get_locus (),
+		     "cannot transmute between types of different sizes, or "
+		     "dependently-sized types");
+      rust_inform (fntype->get_ident ().locus, "source type: %qs (%lu bits)",
+		   fntype->get_params ().at (0).second->as_string ().c_str (),
+		   source_size);
+      rust_inform (fntype->get_ident ().locus, "target type: %qs (%lu bits)",
+		   fntype->get_return_type ()->as_string ().c_str (),
+		   target_size);
+    }
+
   tree enclosing_scope = NULL_TREE;
   Location start_location = Location ();
   Location end_location = Location ();
diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h
index 39bb9d2f899..c4817ad620c 100644
--- a/gcc/rust/hir/tree/rust-hir-type.h
+++ b/gcc/rust/hir/tree/rust-hir-type.h
@@ -582,10 +582,7 @@ public:
   ArrayType (ArrayType const &other)
     : TypeNoBounds (other.mappings), elem_type (other.elem_type->clone_type ()),
       size (other.size->clone_expr ()), locus (other.locus)
-  {
-    // Untested.
-    gcc_unreachable ();
-  }
+  {}
 
   // Overload assignment operator to deep copy pointers
   ArrayType &operator= (ArrayType const &other)
diff --git a/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs b/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs
new file mode 100644
index 00000000000..1aef4d81929
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs
@@ -0,0 +1,11 @@
+mod mem {
+    extern "rust-intrinsic" {
+        fn size_of<T>() -> usize;
+        fn transmute<U, V>(_: U) -> V; // { dg-error "cannot transmute between types of different sizes, or dependently-sized types" }
+    }
+}
+
+fn main() {
+    let a = 123;
+    let _b: [u32; mem::size_of::<i32>()] = mem::transmute(a);
+}


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

only message in thread, other threads:[~2022-06-09  6:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-09  6:16 [gcc/devel/rust/master] rust/intrinsic: add a basic size check for transmute 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).