aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-06-08 15:55:54 +0000
committerGitHub <noreply@github.com>2022-06-08 15:55:54 +0000
commite6d32d59f1e6524df667262c509910e44151bbf2 (patch)
tree8904df62b4caf13af6a683628b5e9b0570861cd9 /gcc
parent8f47bc322cc0e49fd249a63292173821a70d9a53 (diff)
parent188dd73755914865bd138eb886094fb957ab185c (diff)
downloadgcc-e6d32d59f1e6524df667262c509910e44151bbf2.zip
gcc-e6d32d59f1e6524df667262c509910e44151bbf2.tar.gz
gcc-e6d32d59f1e6524df667262c509910e44151bbf2.tar.bz2
Merge #1298
1298: rust/intrinsic: add a basic size check for `transmute` r=philberty a=liushuyu - rust/intrinsic: add a basic size check for `transmute` partially addresses #1195 Co-authored-by: liushuyu <liushuyu011@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.cc32
-rw-r--r--gcc/rust/hir/tree/rust-hir-type.h5
-rw-r--r--gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs11
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 a7225f2..e93480d 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 39bb9d2..c4817ad 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 0000000..1aef4d8
--- /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);
+}