aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2014-05-01 19:18:56 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2014-05-01 19:18:56 +0000
commite14b9135f169d290f59cad9d5fd521d2022955c7 (patch)
treec8f2e8aa8863578dafa94ae1aed58c20613f5004 /gcc/go/gofrontend
parentb6799f373ac288dc5de71240a13488e9e3530f2a (diff)
downloadgcc-e14b9135f169d290f59cad9d5fd521d2022955c7.zip
gcc-e14b9135f169d290f59cad9d5fd521d2022955c7.tar.gz
gcc-e14b9135f169d290f59cad9d5fd521d2022955c7.tar.bz2
compiler: Use backend interface for heap expressions.
From-SVN: r209983
Diffstat (limited to 'gcc/go/gofrontend')
-rw-r--r--gcc/go/gofrontend/expressions.cc43
-rw-r--r--gcc/go/gofrontend/gogo.cc9
2 files changed, 29 insertions, 23 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 2756263..275bee5 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -13798,30 +13798,31 @@ class Heap_expression : public Expression
tree
Heap_expression::do_get_tree(Translate_context* context)
{
- tree expr_tree = this->expr_->get_tree(context);
- if (expr_tree == error_mark_node || TREE_TYPE(expr_tree) == error_mark_node)
+ if (this->expr_->is_error_expression() || this->expr_->type()->is_error())
return error_mark_node;
- Expression* alloc =
- Expression::make_allocation(this->expr_->type(), this->location());
-
+ Location loc = this->location();
Gogo* gogo = context->gogo();
- Btype* btype = this->expr_->type()->get_backend(gogo);
- size_t expr_size = gogo->backend()->type_size(btype);
- tree space = alloc->get_tree(context);
- if (expr_size == 0)
- return space;
-
- space = save_expr(space);
- tree ref = build_fold_indirect_ref_loc(this->location().gcc_location(),
- space);
- TREE_THIS_NOTRAP(ref) = 1;
- tree ret = build2(COMPOUND_EXPR,
- type_to_tree(this->type()->get_backend(gogo)),
- build2(MODIFY_EXPR, void_type_node, ref, expr_tree),
- space);
- SET_EXPR_LOCATION(ret, this->location().gcc_location());
- return ret;
+ Btype* btype = this->type()->get_backend(gogo);
+ Expression* alloc = Expression::make_allocation(this->expr_->type(), loc);
+ Bexpression* space = tree_to_expr(alloc->get_tree(context));
+
+ Bstatement* decl;
+ Named_object* fn = context->function();
+ go_assert(fn != NULL);
+ Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
+ Bvariable* space_temp =
+ gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
+ space, true, loc, &decl);
+ space = gogo->backend()->var_expression(space_temp, loc);
+ Bexpression* ref = gogo->backend()->indirect_expression(space, true, loc);
+
+ Bexpression* bexpr = tree_to_expr(this->expr_->get_tree(context));
+ Bstatement* assn = gogo->backend()->assignment_statement(ref, bexpr, loc);
+ decl = gogo->backend()->compound_statement(decl, assn);
+ space = gogo->backend()->var_expression(space_temp, loc);
+ Bexpression* ret = gogo->backend()->compound_expression(decl, space, loc);
+ return expr_to_tree(ret);
}
// Dump ast representation for a heap expression.
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 995a4f2..ab54f84 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -1147,8 +1147,6 @@ Gogo::write_globals()
Bstatement* var_init_stmt = NULL;
if (!var->has_pre_init())
{
- Bexpression* var_binit = var->get_init(this, NULL);
-
// If the backend representation of the variable initializer is
// constant, we can just set the initial value using
// global_var_set_init instead of during the init() function.
@@ -1168,6 +1166,13 @@ Gogo::write_globals()
init_cast->is_immutable() && !var_type->has_pointer();
}
+ // Non-constant variable initializations might need to create
+ // temporary variables, which will need the initialization
+ // function as context.
+ if (!is_constant_initializer && init_fndecl == NULL)
+ init_fndecl = this->initialization_function_decl();
+ Bexpression* var_binit = var->get_init(this, init_fndecl);
+
if (var_binit == NULL)
;
else if (is_constant_initializer)