diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-base.cc | 5 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-base.h | 2 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.cc | 53 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-implitem.cc | 9 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-item.cc | 9 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 6 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 162 |
7 files changed, 151 insertions, 95 deletions
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index 49f31fc..6773ac6 100644 --- a/gcc/rust/backend/rust-compile-base.cc +++ b/gcc/rust/backend/rust-compile-base.cc @@ -317,7 +317,7 @@ HIRCompileBase::mark_addressable (tree exp, Location locus) } tree -HIRCompileBase::address_expression (tree expr, Location location) +HIRCompileBase::address_expression (tree expr, tree ptrtype, Location location) { if (expr == error_mark_node) return error_mark_node; @@ -325,7 +325,8 @@ HIRCompileBase::address_expression (tree expr, Location location) if (!mark_addressable (expr, location)) return error_mark_node; - return build_fold_addr_expr_loc (location.gcc_location (), expr); + return build_fold_addr_expr_with_type_loc (location.gcc_location (), expr, + ptrtype); } std::vector<Bvariable *> diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h index f12913c..77e6cc3 100644 --- a/gcc/rust/backend/rust-compile-base.h +++ b/gcc/rust/backend/rust-compile-base.h @@ -98,7 +98,7 @@ protected: static void setup_abi_options (tree fndecl, ABI abi); - static tree address_expression (tree, Location); + static tree address_expression (tree expr, tree ptrtype, Location locus); static bool mark_addressable (tree, Location); diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index edeea8d..4225263 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -123,7 +123,14 @@ void CompileExpr::visit (HIR::BorrowExpr &expr) { tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx); - translated = address_expression (main_expr, expr.get_locus ()); + + TyTy::BaseType *tyty = nullptr; + if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), + &tyty)) + return; + + tree ptrtype = TyTyResolveCompile::compile (ctx, tyty); + translated = address_expression (main_expr, ptrtype, expr.get_locus ()); } void @@ -670,17 +677,6 @@ CompileExpr::compile_dyn_dispatch_call (const TyTy::DynamicObjectType *dyn, = ctx->get_backend ()->convert_expression (expected_fntype, fn_vtable_access, expr_locus); - fncontext fnctx = ctx->peek_fn (); - tree enclosing_scope = ctx->peek_enclosing_scope (); - bool is_address_taken = false; - tree ret_var_stmt = NULL_TREE; - Bvariable *fn_convert_expr_tmp - = ctx->get_backend ()->temporary_variable (fnctx.fndecl, enclosing_scope, - expected_fntype, fn_convert_expr, - is_address_taken, expr_locus, - &ret_var_stmt); - ctx->add_statement (ret_var_stmt); - std::vector<tree> args; args.push_back (self_argument); for (auto &argument : arguments) @@ -689,10 +685,7 @@ CompileExpr::compile_dyn_dispatch_call (const TyTy::DynamicObjectType *dyn, args.push_back (compiled_expr); } - tree fn_expr - = ctx->get_backend ()->var_expression (fn_convert_expr_tmp, expr_locus); - - return ctx->get_backend ()->call_expression (fn_expr, args, nullptr, + return ctx->get_backend ()->call_expression (fn_convert_expr, args, nullptr, expr_locus); } @@ -707,7 +700,8 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref, tree fn = NULL_TREE; if (ctx->lookup_function_decl (fntype->get_ty_ref (), &fn)) { - return address_expression (fn, expr_locus); + return address_expression (fn, build_pointer_type (TREE_TYPE (fn)), + expr_locus); } // Now we can try and resolve the address since this might be a forward @@ -983,7 +977,8 @@ CompileExpr::compile_string_literal (const HIR::LiteralExpr &expr, auto base = ctx->get_backend ()->string_constant_expression ( literal_value.as_string ()); - return address_expression (base, expr.get_locus ()); + return address_expression (base, build_pointer_type (TREE_TYPE (base)), + expr.get_locus ()); } tree @@ -1016,7 +1011,8 @@ CompileExpr::compile_byte_string_literal (const HIR::LiteralExpr &expr, vals, expr.get_locus ()); - return address_expression (constructed, expr.get_locus ()); + return address_expression (constructed, build_pointer_type (array_type), + expr.get_locus ()); } tree @@ -1233,8 +1229,11 @@ HIRCompileBase::resolve_adjustements ( return error_mark_node; case Resolver::Adjustment::AdjustmentType::IMM_REF: - case Resolver::Adjustment::AdjustmentType::MUT_REF: - e = address_expression (e, locus); + case Resolver::Adjustment::AdjustmentType::MUT_REF: { + tree ptrtype + = TyTyResolveCompile::compile (ctx, adjustment.get_expected ()); + e = address_expression (e, ptrtype, locus); + } break; case Resolver::Adjustment::AdjustmentType::DEREF: @@ -1280,7 +1279,10 @@ HIRCompileBase::resolve_deref_adjustment (Resolver::Adjustment &adjustment, != Resolver::Adjustment::AdjustmentType::ERROR; if (needs_borrow) { - adjusted_argument = address_expression (expression, locus); + adjusted_argument + = address_expression (expression, + build_reference_type (TREE_TYPE (expression)), + locus); } // make the call @@ -1316,7 +1318,9 @@ HIRCompileBase::resolve_unsized_adjustment (Resolver::Adjustment &adjustment, = TyTyResolveCompile::compile (ctx, adjustment.get_expected ()); // make a constructor for this - tree data = address_expression (expression, locus); + tree data + = address_expression (expression, + build_reference_type (TREE_TYPE (expression)), locus); // fetch the size from the domain tree domain = TYPE_DOMAIN (expr_type); @@ -1414,7 +1418,8 @@ CompileExpr::visit (HIR::IdentifierExpr &expr) else if (ctx->lookup_function_decl (ref, &fn)) { TREE_USED (fn) = 1; - translated = address_expression (fn, expr.get_locus ()); + translated = address_expression (fn, build_pointer_type (TREE_TYPE (fn)), + expr.get_locus ()); } else if (ctx->lookup_var_decl (ref, &var)) { diff --git a/gcc/rust/backend/rust-compile-implitem.cc b/gcc/rust/backend/rust-compile-implitem.cc index 9dc6d14..c13556a 100644 --- a/gcc/rust/backend/rust-compile-implitem.cc +++ b/gcc/rust/backend/rust-compile-implitem.cc @@ -68,7 +68,10 @@ CompileTraitItem::visit (HIR::TraitItemFunc &func) { ctx->insert_function_decl (fntype, lookup); } - reference = address_expression (lookup, ref_locus); + reference + = address_expression (lookup, + build_pointer_type (TREE_TYPE (lookup)), + ref_locus); return; } } @@ -95,7 +98,9 @@ CompileTraitItem::visit (HIR::TraitItemFunc &func) func.get_outer_attrs (), func.get_locus (), func.get_block_expr ().get (), canonical_path, fntype, function.has_return_type ()); - reference = address_expression (fndecl, ref_locus); + reference + = address_expression (fndecl, build_pointer_type (TREE_TYPE (fndecl)), + ref_locus); } } // namespace Compile diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc index 969c852..36fa787 100644 --- a/gcc/rust/backend/rust-compile-item.cc +++ b/gcc/rust/backend/rust-compile-item.cc @@ -146,7 +146,10 @@ CompileItem::visit (HIR::Function &function) ctx->insert_function_decl (fntype, lookup); } - reference = address_expression (lookup, ref_locus); + reference + = address_expression (lookup, + build_pointer_type (TREE_TYPE (lookup)), + ref_locus); return; } } @@ -171,7 +174,9 @@ CompileItem::visit (HIR::Function &function) function.get_outer_attrs (), function.get_locus (), function.get_definition ().get (), canonical_path, fntype, function.has_function_return_type ()); - reference = address_expression (fndecl, ref_locus); + reference + = address_expression (fndecl, build_pointer_type (TREE_TYPE (fndecl)), + ref_locus); } void diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index 55a2fff..bd44bf4 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -141,14 +141,16 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, if (ctx->lookup_function_decl (fntype->get_ty_ref (), &fn)) { TREE_USED (fn) = 1; - return address_expression (fn, expr_locus); + return address_expression (fn, build_pointer_type (TREE_TYPE (fn)), + expr_locus); } else if (fntype->get_abi () == ABI::INTRINSIC) { Intrinsics compile (ctx); fn = compile.compile (fntype); TREE_USED (fn) = 1; - return address_expression (fn, expr_locus); + return address_expression (fn, build_pointer_type (TREE_TYPE (fn)), + expr_locus); } } diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index bd782b0..5c9bbf9 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -202,27 +202,104 @@ HIRCompileBase::coercion_site (tree rvalue, TyTy::BaseType *actual, TyTy::BaseType *expected, Location lvalue_locus, Location rvalue_locus) { - auto root_actual_kind = actual->get_root ()->get_kind (); - auto root_expected_kind = expected->get_root ()->get_kind (); + if (rvalue == error_mark_node) + return error_mark_node; - if (root_expected_kind == TyTy::TypeKind::ARRAY - && root_actual_kind == TyTy::TypeKind::ARRAY) + if (expected->get_kind () == TyTy::TypeKind::REF) { - tree tree_rval_type - = TyTyResolveCompile::compile (ctx, actual->get_root ()); - tree tree_lval_type - = TyTyResolveCompile::compile (ctx, expected->get_root ()); + // bad coercion... of something to a reference + if (actual->get_kind () != TyTy::TypeKind::REF) + return error_mark_node; + + TyTy::ReferenceType *exp = static_cast<TyTy::ReferenceType *> (expected); + TyTy::ReferenceType *act = static_cast<TyTy::ReferenceType *> (actual); + + tree expected_type = TyTyResolveCompile::compile (ctx, act->get_base ()); + tree deref_rvalue + = ctx->get_backend ()->indirect_expression (expected_type, rvalue, + false /*known_valid*/, + rvalue_locus); + tree coerced + = coercion_site (deref_rvalue, act->get_base (), exp->get_base (), + lvalue_locus, rvalue_locus); + + return address_expression (coerced, + build_reference_type (TREE_TYPE (coerced)), + rvalue_locus); + } + else if (expected->get_kind () == TyTy::TypeKind::POINTER) + { + // bad coercion... of something to a reference + bool valid_coercion = actual->get_kind () == TyTy::TypeKind::REF + || actual->get_kind () == TyTy::TypeKind::POINTER; + if (!valid_coercion) + return error_mark_node; + + TyTy::ReferenceType *exp = static_cast<TyTy::ReferenceType *> (expected); + + TyTy::BaseType *actual_base = nullptr; + tree expected_type = error_mark_node; + if (actual->get_kind () == TyTy::TypeKind::REF) + { + TyTy::ReferenceType *act + = static_cast<TyTy::ReferenceType *> (actual); + actual_base = act->get_base (); + expected_type = TyTyResolveCompile::compile (ctx, act->get_base ()); + } + else if (actual->get_kind () == TyTy::TypeKind::POINTER) + { + TyTy::PointerType *act = static_cast<TyTy::PointerType *> (actual); + actual_base = act->get_base (); + expected_type = TyTyResolveCompile::compile (ctx, act->get_base ()); + } + rust_assert (actual_base != nullptr); + + tree deref_rvalue + = ctx->get_backend ()->indirect_expression (expected_type, rvalue, + false /*known_valid*/, + rvalue_locus); + tree coerced = coercion_site (deref_rvalue, actual_base, exp->get_base (), + lvalue_locus, rvalue_locus); + + return address_expression (coerced, + build_pointer_type (TREE_TYPE (coerced)), + rvalue_locus); + } + else if (expected->get_kind () == TyTy::TypeKind::ARRAY) + { + if (actual->get_kind () != TyTy::TypeKind::ARRAY) + return error_mark_node; + + tree tree_rval_type = TyTyResolveCompile::compile (ctx, actual); + tree tree_lval_type = TyTyResolveCompile::compile (ctx, expected); if (!verify_array_capacities (tree_lval_type, tree_rval_type, lvalue_locus, rvalue_locus)) return error_mark_node; } - else if (root_expected_kind == TyTy::TypeKind::DYNAMIC - && root_actual_kind != TyTy::TypeKind::DYNAMIC) + else if (expected->get_kind () == TyTy::TypeKind::DYNAMIC + && actual->get_kind () != TyTy::TypeKind::DYNAMIC) { const TyTy::DynamicObjectType *dyn - = static_cast<const TyTy::DynamicObjectType *> (expected->get_root ()); + = static_cast<const TyTy::DynamicObjectType *> (expected); return coerce_to_dyn_object (rvalue, actual, expected, dyn, rvalue_locus); } + else if (expected->get_kind () == TyTy::TypeKind::SLICE) + { + // bad coercion + bool valid_coercion = actual->get_kind () == TyTy::TypeKind::SLICE + || actual->get_kind () == TyTy::TypeKind::ARRAY; + if (!valid_coercion) + return error_mark_node; + + // nothing to do here + if (actual->get_kind () == TyTy::TypeKind::SLICE) + return rvalue; + + // return an unsized coercion + Resolver::Adjustment unsize_adj ( + Resolver::Adjustment::AdjustmentType::UNSIZE, expected); + return resolve_unsized_adjustment (unsize_adj, rvalue, rvalue_locus); + } return rvalue; } @@ -240,12 +317,17 @@ HIRCompileBase::coerce_to_dyn_object (tree compiled_ref, // __trait_object_ptr // [list of function ptrs] - auto root = actual->get_root (); std::vector<std::pair<Resolver::TraitReference *, HIR::ImplBlock *>> - probed_bounds_for_receiver = Resolver::TypeBoundsProbe::Probe (root); - + probed_bounds_for_receiver = Resolver::TypeBoundsProbe::Probe (actual); + + tree address_of_compiled_ref = null_pointer_node; + if (!actual->is_unit ()) + address_of_compiled_ref + = address_expression (compiled_ref, + build_pointer_type (TREE_TYPE (compiled_ref)), + locus); std::vector<tree> vals; - vals.push_back (compiled_ref); + vals.push_back (address_of_compiled_ref); for (auto &bound : ty->get_object_items ()) { const Resolver::TraitItemReference *item = bound.first; @@ -253,56 +335,12 @@ HIRCompileBase::coerce_to_dyn_object (tree compiled_ref, auto address = compute_address_for_trait_item (item, predicate, probed_bounds_for_receiver, - actual, root, locus); + actual, actual, locus); vals.push_back (address); } - tree constructed_trait_object - = ctx->get_backend ()->constructor_expression (dynamic_object, false, vals, - -1, locus); - - fncontext fnctx = ctx->peek_fn (); - tree enclosing_scope = ctx->peek_enclosing_scope (); - bool is_address_taken = false; - tree ret_var_stmt = NULL_TREE; - - Bvariable *dyn_tmp = ctx->get_backend ()->temporary_variable ( - fnctx.fndecl, enclosing_scope, dynamic_object, constructed_trait_object, - is_address_taken, locus, &ret_var_stmt); - ctx->add_statement (ret_var_stmt); - - // FIXME this needs to be more generic to apply any covariance - - auto e = expected; - std::vector<Resolver::Adjustment> adjustments; - while (e->get_kind () == TyTy::TypeKind::REF) - { - auto r = static_cast<const TyTy::ReferenceType *> (e); - e = r->get_base (); - - if (r->is_mutable ()) - adjustments.push_back ( - Resolver::Adjustment (Resolver::Adjustment::AdjustmentType::MUT_REF, - e)); - else - adjustments.push_back ( - Resolver::Adjustment (Resolver::Adjustment::AdjustmentType::IMM_REF, - e)); - } - - auto resulting_dyn_object_ref - = ctx->get_backend ()->var_expression (dyn_tmp, locus); - for (auto it = adjustments.rbegin (); it != adjustments.rend (); it++) - { - bool ok - = it->get_type () == Resolver::Adjustment::AdjustmentType::IMM_REF - || it->get_type () == Resolver::Adjustment::AdjustmentType::MUT_REF; - rust_assert (ok); - - resulting_dyn_object_ref - = address_expression (resulting_dyn_object_ref, locus); - } - return resulting_dyn_object_ref; + return ctx->get_backend ()->constructor_expression (dynamic_object, false, + vals, -1, locus); } tree |