]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
compiler: Use backend interface for heap expressions.
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 1 May 2014 19:18:56 +0000 (19:18 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 1 May 2014 19:18:56 +0000 (19:18 +0000)
From-SVN: r209983

gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/gogo.cc

index 275626391767ebf0db179c8d18816f7d01b6ccef..275bee53e0d185a3452487ad681e2309cd17fb7d 100644 (file)
@@ -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.
index 995a4f2d2da32b53f39ed90446d8bd4573e70c21..ab54f8491e3c56a17b422b97eef25eaae55cfe0a 100644 (file)
@@ -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)