diff options
author | Philip Herron <philip.herron@embecosm.com> | 2022-05-23 10:46:59 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2022-05-23 13:49:01 +0100 |
commit | cd39861da5e1113207193bb8b3e6fb3dde92895f (patch) | |
tree | b12ed1fc0c7f4bcddbb38ff51cae7aea393b7a40 /gcc/rust/backend/rust-compile-expr.cc | |
parent | c7008d3e254786b5e752aa61e067f62c38042b81 (diff) | |
download | gcc-cd39861da5e1113207193bb8b3e6fb3dde92895f.zip gcc-cd39861da5e1113207193bb8b3e6fb3dde92895f.tar.gz gcc-cd39861da5e1113207193bb8b3e6fb3dde92895f.tar.bz2 |
Fix Slice Type Layout
Slices in Rust are represented by TypePaths such as '[i32]'. Though if you
actually try to use this explicit type-path you will hit errors such as
this type has an unknown size at compile time. This is because this is
actually what Rust calls a dynamically sized type. This means when you use
types such as: '&[i32]' it is not actually a reference type to a slice. Its
a slice in its entirety this means for lack of a better word when you use
'*const [i32]' or '&mut [i32]' we end up actually passing around a struct
by value _not_ at pointer/reference to it.
This patch changes the type-layout so that we handle this layout change
properly. This patch will also need to be applied to str types which I
believe have a similar layout for safety.
The patch also sets up TYPE_MAIN_VARIANT so that we can avoid unnessecary
view_convert_expressions between *const [i32] and &mut [i32] which will
have the same layout.
Reference:
https://doc.rust-lang.org/reference/dynamically-sized-types.html
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=672adac002939a2dab43b8d231adc1dc
Fixes #1232
Diffstat (limited to 'gcc/rust/backend/rust-compile-expr.cc')
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.cc | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 824d6d3..b176ed2 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -123,6 +123,11 @@ void CompileExpr::visit (HIR::BorrowExpr &expr) { tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx); + if (SLICE_TYPE_P (TREE_TYPE (main_expr))) + { + translated = main_expr; + return; + } TyTy::BaseType *tyty = nullptr; if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), @@ -164,6 +169,12 @@ CompileExpr::visit (HIR::DereferenceExpr &expr) } tree expected_type = TyTyResolveCompile::compile (ctx, tyty); + if (SLICE_TYPE_P (TREE_TYPE (main_expr)) && SLICE_TYPE_P (expected_type)) + { + translated = main_expr; + return; + } + bool known_valid = true; translated = ctx->get_backend ()->indirect_expression (expected_type, main_expr, @@ -1092,6 +1103,32 @@ CompileExpr::type_cast_expression (tree type_to_cast_to, tree expr_tree, return fold_build1_loc (location.gcc_location (), VIEW_CONVERT_EXPR, type_to_cast_to, expr_tree); } + else if (TREE_CODE (type_to_cast_to) == POINTER_TYPE + && SLICE_TYPE_P (TREE_TYPE (expr_tree))) + { + // returning a raw cast using NOP_EXPR seems to resut in an ICE: + // + // Analyzing compilation unit + // Performing interprocedural optimizations + // <*free_lang_data> {heap 2644k} <visibility> {heap 2644k} + // <build_ssa_passes> {heap 2644k} <opt_local_passes> {heap 2644k}during + // GIMPLE pass: cddce + // In function ‘*T::as_ptr<i32>’: + // rust1: internal compiler error: in propagate_necessity, at + // tree-ssa-dce.cc:984 0x1d5b43e propagate_necessity + // ../../gccrs/gcc/tree-ssa-dce.cc:984 + // 0x1d5e180 perform_tree_ssa_dce + // ../../gccrs/gcc/tree-ssa-dce.cc:1876 + // 0x1d5e2c8 tree_ssa_cd_dce + // ../../gccrs/gcc/tree-ssa-dce.cc:1920 + // 0x1d5e49a execute + // ../../gccrs/gcc/tree-ssa-dce.cc:1992 + + // this is returning the direct raw pointer of the slice an assumes a very + // specific layout + return ctx->get_backend ()->struct_field_expression (expr_tree, 0, + location); + } return fold_convert_loc (location.gcc_location (), type_to_cast_to, expr_tree); @@ -1261,9 +1298,13 @@ HIRCompileBase::resolve_adjustements ( case Resolver::Adjustment::AdjustmentType::IMM_REF: case Resolver::Adjustment::AdjustmentType::MUT_REF: { - tree ptrtype - = TyTyResolveCompile::compile (ctx, adjustment.get_expected ()); - e = address_expression (e, ptrtype, locus); + if (!SLICE_TYPE_P (TREE_TYPE (e))) + { + tree ptrtype + = TyTyResolveCompile::compile (ctx, + adjustment.get_expected ()); + e = address_expression (e, ptrtype, locus); + } } break; @@ -1619,6 +1660,15 @@ CompileExpr::visit (HIR::ArrayIndexExpr &expr) index, expr.get_array_expr (), expr.get_index_expr ()); + tree actual_type = TREE_TYPE (operator_overload_call); + bool can_indirect = TYPE_PTR_P (actual_type) || TYPE_REF_P (actual_type); + if (!can_indirect) + { + // nothing to do + translated = operator_overload_call; + return; + } + // lookup the expected type for this expression TyTy::BaseType *tyty = nullptr; bool ok |