From: Ian Lance Taylor Date: Thu, 1 May 2014 19:18:56 +0000 (+0000) Subject: compiler: Use backend interface for heap expressions. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e14b9135f169d290f59cad9d5fd521d2022955c7;p=gcc.git compiler: Use backend interface for heap expressions. From-SVN: r209983 --- diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 27562639176..275bee53e0d 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 995a4f2d2da..ab54f8491e3 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)