From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id 7E1A6385AE71; Thu, 9 Jun 2022 06:16:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7E1A6385AE71 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Thomas Schwinge To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] rust/intrinsic: add a basic size check for transmute X-Act-Checkin: gcc X-Git-Author: liushuyu X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: 957914b4284213b1d72c9c4210892367acaf1419 X-Git-Newrev: 188dd73755914865bd138eb886094fb957ab185c Message-Id: <20220609061654.7E1A6385AE71@sourceware.org> Date: Thu, 9 Jun 2022 06:16:54 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Jun 2022 06:16:54 -0000 https://gcc.gnu.org/g:188dd73755914865bd138eb886094fb957ab185c commit 188dd73755914865bd138eb886094fb957ab185c Author: liushuyu 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 param_vars; + std::vector 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() -> usize; + fn transmute(_: 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::()] = mem::transmute(a); +}