aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-base.cc5
-rw-r--r--gcc/rust/backend/rust-compile-base.h2
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc53
-rw-r--r--gcc/rust/backend/rust-compile-implitem.cc9
-rw-r--r--gcc/rust/backend/rust-compile-item.cc9
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc6
-rw-r--r--gcc/rust/backend/rust-compile.cc162
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