public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Thomas Schwinge <tschwinge@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc/devel/rust/master] rust/intrinsic: add a basic size check for transmute
Date: Thu,  9 Jun 2022 06:16:54 +0000 (GMT)	[thread overview]
Message-ID: <20220609061654.7E1A6385AE71@sourceware.org> (raw)

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);
+}


                 reply	other threads:[~2022-06-09  6:16 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220609061654.7E1A6385AE71@sourceware.org \
    --to=tschwinge@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).