diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-06-08 15:55:54 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-08 15:55:54 +0000 |
commit | e6d32d59f1e6524df667262c509910e44151bbf2 (patch) | |
tree | 8904df62b4caf13af6a683628b5e9b0570861cd9 /gcc | |
parent | 8f47bc322cc0e49fd249a63292173821a70d9a53 (diff) | |
parent | 188dd73755914865bd138eb886094fb957ab185c (diff) | |
download | gcc-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.cc | 32 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-type.h | 5 | ||||
-rw-r--r-- | gcc/testsuite/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 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); +} |