diff mbox

Go patch committed: Use backend interface for zero initialization

Message ID mcrr572zkyq.fsf@coign.corp.google.com
State New
Headers show

Commit Message

Ian Lance Taylor June 9, 2011, 10:41 p.m. UTC
This patch to the Go frontend uses the backend interface for zero
initialization.  This basically removes quite a bit of unnecessary code,
which was more flexible than it ever really needed to be.  Bootstrapped
and ran Go testsuite on x86_64-unknown-linux-gnu.  Committed to
mainline.

Ian


2011-06-09  Ian Lance Taylor  <iant@google.com>

	* go-gcc.cc (Gcc_backend::zero_expression): New function.
diff mbox

Patch

Index: gcc/go/go-gcc.cc
===================================================================
--- gcc/go/go-gcc.cc	(revision 174810)
+++ gcc/go/go-gcc.cc	(working copy)
@@ -194,6 +194,11 @@  class Gcc_backend : public Backend
   bool
   is_circular_pointer_type(Btype*);
 
+  // Expressions.
+
+  Bexpression*
+  zero_expression(Btype*);
+
   // Statements.
 
   Bstatement*
@@ -700,6 +705,20 @@  Gcc_backend::is_circular_pointer_type(Bt
   return btype->get_tree() == ptr_type_node;
 }
 
+// Return the zero value for a type.
+
+Bexpression*
+Gcc_backend::zero_expression(Btype* btype)
+{
+  tree t = btype->get_tree();
+  tree ret;
+  if (t == error_mark_node)
+    ret = error_mark_node;
+  else
+    ret = build_zero_cst(t);
+  return tree_to_expr(ret);
+}
+
 // An expression as a statement.
 
 Bstatement*
Index: gcc/go/gofrontend/gogo.cc
===================================================================
--- gcc/go/gofrontend/gogo.cc	(revision 174810)
+++ gcc/go/gofrontend/gogo.cc	(working copy)
@@ -1498,6 +1498,10 @@  Check_types_traverse::variable(Named_obj
   if (named_object->is_variable())
     {
       Variable* var = named_object->var_value();
+
+      // Give error if variable type is not defined.
+      var->type()->base();
+
       Expression* init = var->init();
       std::string reason;
       if (init != NULL
Index: gcc/go/gofrontend/types.h
===================================================================
--- gcc/go/gofrontend/types.h	(revision 174810)
+++ gcc/go/gofrontend/types.h	(working copy)
@@ -825,19 +825,6 @@  class Type
   Btype*
   get_backend(Gogo*);
 
-  // Return a tree representing a zero initialization for this type.
-  // This will be something like an INTEGER_CST or a CONSTRUCTOR.  If
-  // IS_CLEAR is true, then the memory is known to be zeroed; in that
-  // case, this will return NULL if there is nothing to be done.
-  tree
-  get_init_tree(Gogo*, bool is_clear);
-
-  // Like get_init_tree, but passing in the type to use for the
-  // initializer.
-  tree
-  get_typed_init_tree(Gogo* gogo, tree type_tree, bool is_clear)
-  { return this->do_get_init_tree(gogo, type_tree, is_clear); }
-
   // Return a tree for a make expression applied to this type.
   tree
   make_expression_tree(Translate_context* context, Expression_list* args,
@@ -896,9 +883,6 @@  class Type
   do_get_backend(Gogo*) = 0;
 
   virtual tree
-  do_get_init_tree(Gogo*, tree, bool) = 0;
-
-  virtual tree
   do_make_expression_tree(Translate_context*, Expression_list*,
 			  source_location);
 
@@ -1334,9 +1318,6 @@  class Integer_type : public Type
   Btype*
   do_get_backend(Gogo*);
 
-  tree
-  do_get_init_tree(Gogo*, tree, bool);
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*);
 
@@ -1406,9 +1387,6 @@  class Float_type : public Type
   Btype*
   do_get_backend(Gogo*);
 
-  tree
-  do_get_init_tree(Gogo*, tree, bool);
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*);
 
@@ -1474,9 +1452,6 @@  class Complex_type : public Type
   Btype*
   do_get_backend(Gogo*);
 
-  tree
-  do_get_init_tree(Gogo*, tree, bool);
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*);
 
@@ -1530,9 +1505,6 @@  class String_type : public Type
   Btype*
   do_get_backend(Gogo*);
 
-  tree
-  do_get_init_tree(Gogo* gogo, tree, bool);
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*);
 
@@ -1650,9 +1622,6 @@  class Function_type : public Type
   Btype*
   do_get_backend(Gogo*);
 
-  tree
-  do_get_init_tree(Gogo*, tree, bool);
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*);
 
@@ -1734,9 +1703,6 @@  class Pointer_type : public Type
   Btype*
   do_get_backend(Gogo*);
 
-  tree
-  do_get_init_tree(Gogo*, tree, bool);
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*);
 
@@ -1988,9 +1954,6 @@  class Struct_type : public Type
   Btype*
   do_get_backend(Gogo*);
 
-  tree
-  do_get_init_tree(Gogo*, tree, bool);
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*);
 
@@ -2106,9 +2069,6 @@  class Array_type : public Type
   do_get_backend(Gogo*);
 
   tree
-  do_get_init_tree(Gogo*, tree, bool);
-
-  tree
   do_make_expression_tree(Translate_context*, Expression_list*,
 			  source_location);
 
@@ -2197,9 +2157,6 @@  class Map_type : public Type
   do_get_backend(Gogo*);
 
   tree
-  do_get_init_tree(Gogo*, tree, bool);
-
-  tree
   do_make_expression_tree(Translate_context*, Expression_list*,
 			  source_location);
 
@@ -2281,9 +2238,6 @@  class Channel_type : public Type
   do_get_backend(Gogo*);
 
   tree
-  do_get_init_tree(Gogo*, tree, bool);
-
-  tree
   do_make_expression_tree(Translate_context*, Expression_list*,
 			  source_location);
 
@@ -2398,9 +2352,6 @@  class Interface_type : public Type
   Btype*
   do_get_backend(Gogo*);
 
-  tree
-  do_get_init_tree(Gogo* gogo, tree, bool);
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*);
 
@@ -2630,10 +2581,6 @@  class Named_type : public Type
   do_get_backend(Gogo*);
 
   tree
-  do_get_init_tree(Gogo* gogo, tree type_tree, bool is_clear)
-  { return this->type_->get_typed_init_tree(gogo, type_tree, is_clear); }
-
-  tree
   do_make_expression_tree(Translate_context* context, Expression_list* args,
 			  source_location location)
   { return this->type_->make_expression_tree(context, args, location); }
@@ -2774,10 +2721,6 @@  class Forward_declaration_type : public 
   do_get_backend(Gogo* gogo);
 
   tree
-  do_get_init_tree(Gogo* gogo, tree type_tree, bool is_clear)
-  { return this->base()->get_typed_init_tree(gogo, type_tree, is_clear); }
-
-  tree
   do_make_expression_tree(Translate_context* context, Expression_list* args,
 			  source_location location)
   { return this->base()->make_expression_tree(context, args, location); }
Index: gcc/go/gofrontend/gogo-tree.cc
===================================================================
--- gcc/go/gofrontend/gogo-tree.cc	(revision 174810)
+++ gcc/go/gofrontend/gogo-tree.cc	(working copy)
@@ -1035,9 +1035,10 @@  Variable::get_init_tree(Gogo* gogo, Name
   if (this->init_ == NULL)
     {
       go_assert(!this->is_parameter_);
-      return this->type_->get_init_tree(gogo,
-					(this->is_global_
-					 || this->is_in_heap()));
+      if (this->is_global_ || this->is_in_heap())
+	return NULL;
+      Btype* btype = this->type_->get_backend(gogo);
+      return expr_to_tree(gogo->backend()->zero_expression(btype));
     }
   else
     {
@@ -1286,7 +1287,8 @@  Function::make_receiver_parm_decl(Gogo* 
 						null_pointer_node));
   tree ind = build_fold_indirect_ref_loc(loc, parm_decl);
   TREE_THIS_NOTRAP(ind) = 1;
-  tree zero_init = no->var_value()->type()->get_init_tree(gogo, false);
+  Btype* btype = no->var_value()->type()->get_backend(gogo);
+  tree zero_init = expr_to_tree(gogo->backend()->zero_expression(btype));
   tree init = fold_build3_loc(loc, COND_EXPR, TREE_TYPE(ind),
 			      check, ind, zero_init);
 
@@ -1423,7 +1425,10 @@  Function::build_tree(Gogo* gogo, Named_o
 	  Type* type = (*p)->result_var_value()->type();
 	  tree init;
 	  if (!(*p)->result_var_value()->is_in_heap())
-	    init = type->get_init_tree(gogo, false);
+	    {
+	      Btype* btype = type->get_backend(gogo);
+	      init = expr_to_tree(gogo->backend()->zero_expression(btype));
+	    }
 	  else
 	    {
 	      source_location loc = (*p)->location();
@@ -1432,20 +1437,7 @@  Function::build_tree(Gogo* gogo, Named_o
 						 TYPE_SIZE_UNIT(type_tree),
 						 loc);
 	      tree ptr_type_tree = build_pointer_type(type_tree);
-	      tree subinit = type->get_init_tree(gogo, true);
-	      if (subinit == NULL_TREE)
-		init = fold_convert_loc(loc, ptr_type_tree, space);
-	      else
-		{
-		  space = save_expr(space);
-		  space = fold_convert_loc(loc, ptr_type_tree, space);
-		  tree spaceref = build_fold_indirect_ref_loc(loc, space);
-		  TREE_THIS_NOTRAP(spaceref) = 1;
-		  tree set = fold_build2_loc(loc, MODIFY_EXPR, void_type_node,
-					     spaceref, subinit);
-		  init = fold_build2_loc(loc, COMPOUND_EXPR, TREE_TYPE(space),
-					 set, space);
-		}
+	      init = fold_convert_loc(loc, ptr_type_tree, space);
 	    }
 
 	  if (var_decl != error_mark_node)
Index: gcc/go/gofrontend/backend.h
===================================================================
--- gcc/go/gofrontend/backend.h	(revision 174810)
+++ gcc/go/gofrontend/backend.h	(working copy)
@@ -198,6 +198,14 @@  class Backend
   virtual bool
   is_circular_pointer_type(Btype*) = 0;
 
+  // Expressions.
+
+  // Return an expression for a zero value of the given type.  This is
+  // used for cases such as local variable initialization and
+  // converting nil to other types.
+  virtual Bexpression*
+  zero_expression(Btype*) = 0;
+
   // Statements.
 
   // Create an error statement.  This is used for cases which should
Index: gcc/go/gofrontend/types.cc
===================================================================
--- gcc/go/gofrontend/types.cc	(revision 174810)
+++ gcc/go/gofrontend/types.cc	(working copy)
@@ -913,17 +913,6 @@  Type::get_btype_without_hash(Gogo* gogo)
   return this->btype_;
 }
 
-// Return a tree representing a zero initialization for this type.
-
-tree
-Type::get_init_tree(Gogo* gogo, bool is_clear)
-{
-  tree type_tree = type_to_tree(this->get_backend(gogo));
-  if (type_tree == error_mark_node)
-    return error_mark_node;
-  return this->do_get_init_tree(gogo, type_tree, is_clear);
-}
-
 // Any type which supports the builtin make function must implement
 // this.
 
@@ -1609,10 +1598,6 @@  class Error_type : public Type
   do_get_backend(Gogo* gogo)
   { return gogo->backend()->error_type(); }
 
-  tree
-  do_get_init_tree(Gogo*, tree, bool)
-  { return error_mark_node; }
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*)
   { return Expression::make_error(BUILTINS_LOCATION); }
@@ -1647,10 +1632,6 @@  class Void_type : public Type
   do_get_backend(Gogo* gogo)
   { return gogo->backend()->void_type(); }
 
-  tree
-  do_get_init_tree(Gogo*, tree, bool)
-  { go_unreachable(); }
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*)
   { go_unreachable(); }
@@ -1685,10 +1666,6 @@  class Boolean_type : public Type
   do_get_backend(Gogo* gogo)
   { return gogo->backend()->bool_type(); }
 
-  tree
-  do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-  { return is_clear ? NULL : fold_convert(type_tree, boolean_false_node); }
-
   Expression*
   do_type_descriptor(Gogo*, Named_type* name);
 
@@ -1830,12 +1807,6 @@  Integer_type::do_get_backend(Gogo* gogo)
   return gogo->backend()->integer_type(this->is_unsigned_, this->bits_);
 }
 
-tree
-Integer_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
-  return is_clear ? NULL : build_int_cst(type_tree, 0);
-}
-
 // The type descriptor for an integer type.  Integer types are always
 // named.
 
@@ -1963,16 +1934,6 @@  Float_type::do_get_backend(Gogo* gogo)
   return gogo->backend()->float_type(this->bits_);
 }
 
-tree
-Float_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
-  if (is_clear)
-    return NULL;
-  REAL_VALUE_TYPE r;
-  real_from_integer(&r, TYPE_MODE(type_tree), 0, 0, 0);
-  return build_real(type_tree, r);
-}
-
 // The type descriptor for a float type.  Float types are always named.
 
 Expression*
@@ -2099,19 +2060,6 @@  Complex_type::do_get_backend(Gogo* gogo)
   return gogo->backend()->complex_type(this->bits_);
 }
 
-// Zero initializer.
-
-tree
-Complex_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
-  if (is_clear)
-    return NULL;
-  REAL_VALUE_TYPE r;
-  real_from_integer(&r, TYPE_MODE(TREE_TYPE(type_tree)), 0, 0, 0);
-  return build_complex(type_tree, build_real(TREE_TYPE(type_tree), r),
-		       build_real(TREE_TYPE(type_tree), r));
-}
-
 // The type descriptor for a complex type.  Complex types are always
 // named.
 
@@ -2223,32 +2171,6 @@  String_type::bytes_tree(Gogo*, tree stri
 		     bytes_field, NULL_TREE);
 }
 
-// We initialize a string to { NULL, 0 }.
-
-tree
-String_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
-  if (is_clear)
-    return NULL_TREE;
-
-  go_assert(TREE_CODE(type_tree) == RECORD_TYPE);
-
-  VEC(constructor_elt, gc)* init = VEC_alloc(constructor_elt, gc, 2);
-
-  for (tree field = TYPE_FIELDS(type_tree);
-       field != NULL_TREE;
-       field = DECL_CHAIN(field))
-    {
-      constructor_elt* elt = VEC_quick_push(constructor_elt, init, NULL);
-      elt->index = field;
-      elt->value = fold_convert(TREE_TYPE(field), size_zero_node);
-    }
-
-  tree ret = build_constructor(type_tree, init);
-  TREE_CONSTANT(ret) = 1;
-  return ret;
-}
-
 // The type descriptor for the string type.
 
 Expression*
@@ -2330,10 +2252,6 @@  class Sink_type : public Type
   do_get_backend(Gogo*)
   { go_unreachable(); }
 
-  tree
-  do_get_init_tree(Gogo*, tree, bool)
-  { go_unreachable(); }
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*)
   { go_unreachable(); }
@@ -2704,16 +2622,6 @@  Function_type::convert_types(Gogo* gogo)
     }
 }
 
-// Functions are initialized to NULL.
-
-tree
-Function_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
-  if (is_clear)
-    return NULL;
-  return fold_convert(type_tree, null_pointer_node);
-}
-
 // The type of a function type descriptor.
 
 Type*
@@ -3109,16 +3017,6 @@  Pointer_type::do_get_backend(Gogo* gogo)
   return gogo->backend()->pointer_type(to_btype);
 }
 
-// Initialize a pointer type.
-
-tree
-Pointer_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
-  if (is_clear)
-    return NULL;
-  return fold_convert(type_tree, null_pointer_node);
-}
-
 // The type of a pointer type descriptor.
 
 Type*
@@ -3262,10 +3160,6 @@  class Nil_type : public Type
   do_get_backend(Gogo* gogo)
   { return gogo->backend()->pointer_type(gogo->backend()->void_type()); }
 
-  tree
-  do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-  { return is_clear ? NULL : fold_convert(type_tree, null_pointer_node); }
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*)
   { go_unreachable(); }
@@ -3316,13 +3210,6 @@  class Call_multiple_result_type : public
     return gogo->backend()->error_type();
   }
 
-  tree
-  do_get_init_tree(Gogo*, tree, bool)
-  {
-    go_assert(saw_errors());
-    return error_mark_node;
-  }
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*)
   {
@@ -3823,63 +3710,6 @@  Struct_type::do_get_backend(Gogo* gogo)
   return gogo->backend()->struct_type(bfields);
 }
 
-// Initialize struct fields.
-
-tree
-Struct_type::do_get_init_tree(Gogo* gogo, tree type_tree, bool is_clear)
-{
-  if (this->fields_ == NULL || this->fields_->empty())
-    {
-      if (is_clear)
-	return NULL;
-      else
-	{
-	  tree ret = build_constructor(type_tree,
-				       VEC_alloc(constructor_elt, gc, 0));
-	  TREE_CONSTANT(ret) = 1;
-	  return ret;
-	}
-    }
-
-  bool is_constant = true;
-  bool any_fields_set = false;
-  VEC(constructor_elt,gc)* init = VEC_alloc(constructor_elt, gc,
-					    this->fields_->size());
-
-  tree field = TYPE_FIELDS(type_tree);
-  for (Struct_field_list::const_iterator p = this->fields_->begin();
-       p != this->fields_->end();
-       ++p, field = DECL_CHAIN(field))
-    {
-      tree value = p->type()->get_init_tree(gogo, is_clear);
-      if (value == error_mark_node)
-	return error_mark_node;
-      go_assert(field != NULL_TREE);
-      if (value != NULL)
-	{
-	  constructor_elt* elt = VEC_quick_push(constructor_elt, init, NULL);
-	  elt->index = field;
-	  elt->value = value;
-	  any_fields_set = true;
-	  if (!TREE_CONSTANT(value))
-	    is_constant = false;
-	}
-    }
-  go_assert(field == NULL_TREE);
-
-  if (!any_fields_set)
-    {
-      go_assert(is_clear);
-      VEC_free(constructor_elt, gc, init);
-      return NULL;
-    }
-
-  tree ret = build_constructor(type_tree, init);
-  if (is_constant)
-    TREE_CONSTANT(ret) = 1;
-  return ret;
-}
-
 // The type of a struct type descriptor.
 
 Type*
@@ -4503,61 +4333,6 @@  Array_type::get_backend_length(Gogo* gog
   return tree_to_expr(this->get_length_tree(gogo));
 }
 
-// Return an initializer for an array type.
-
-tree
-Array_type::do_get_init_tree(Gogo* gogo, tree type_tree, bool is_clear)
-{
-  if (this->length_ == NULL)
-    {
-      // Open array.
-
-      if (is_clear)
-	return NULL;
-
-      go_assert(TREE_CODE(type_tree) == RECORD_TYPE);
-
-      VEC(constructor_elt,gc)* init = VEC_alloc(constructor_elt, gc, 3);
-
-      for (tree field = TYPE_FIELDS(type_tree);
-	   field != NULL_TREE;
-	   field = DECL_CHAIN(field))
-	{
-	  constructor_elt* elt = VEC_quick_push(constructor_elt, init,
-						NULL);
-	  elt->index = field;
-	  elt->value = fold_convert(TREE_TYPE(field), size_zero_node);
-	}
-
-      tree ret = build_constructor(type_tree, init);
-      TREE_CONSTANT(ret) = 1;
-      return ret;
-    }
-  else
-    {
-      // Fixed array.
-
-      tree value = this->element_type_->get_init_tree(gogo, is_clear);
-      if (value == NULL)
-	return NULL;
-      if (value == error_mark_node)
-	return error_mark_node;
-
-      tree length_tree = this->get_length_tree(gogo);
-      if (length_tree == error_mark_node)
-	return error_mark_node;
-
-      length_tree = fold_convert(sizetype, length_tree);
-      tree range = build2(RANGE_EXPR, sizetype, size_zero_node,
-			  fold_build2(MINUS_EXPR, sizetype,
-				      length_tree, size_one_node));
-      tree ret = build_constructor_single(type_tree, range, value);
-      if (TREE_CONSTANT(value))
-	TREE_CONSTANT(ret) = 1;
-      return ret;
-    }
-}
-
 // Handle the builtin make function for a slice.
 
 tree
@@ -4585,10 +4360,6 @@  Array_type::do_make_expression_tree(Tran
     return error_mark_node;
   tree element_size_tree = TYPE_SIZE_UNIT(element_type_tree);
 
-  tree value = this->element_type_->get_init_tree(gogo, true);
-  if (value == error_mark_node)
-    return error_mark_node;
-
   // The first argument is the number of elements, the optional second
   // argument is the capacity.
   go_assert(args != NULL && args->size() >= 1 && args->size() <= 2);
@@ -4670,9 +4441,6 @@  Array_type::do_make_expression_tree(Tran
   tree space = context->gogo()->allocate_memory(this->element_type_,
 						size_tree, location);
 
-  if (value != NULL_TREE)
-    space = save_expr(space);
-
   space = fold_convert(TREE_TYPE(values_field), space);
 
   if (bad_index != NULL_TREE && bad_index != boolean_false_node)
@@ -4685,37 +4453,7 @@  Array_type::do_make_expression_tree(Tran
 		     space);
     }
 
-  tree constructor = gogo->slice_constructor(type_tree, space, length_tree,
-					     capacity_tree);
-
-  if (value == NULL_TREE)
-    {
-      // The array contents are zero initialized.
-      return constructor;
-    }
-
-  // The elements must be initialized.
-
-  tree max = fold_build2_loc(location, MINUS_EXPR, TREE_TYPE(count_field),
-			     capacity_tree,
-			     fold_convert_loc(location, TREE_TYPE(count_field),
-					      integer_one_node));
-
-  tree array_type = build_array_type(element_type_tree,
-				     build_index_type(max));
-
-  tree value_pointer = fold_convert_loc(location,
-					build_pointer_type(array_type),
-					space);
-
-  tree range = build2(RANGE_EXPR, sizetype, size_zero_node, max);
-  tree space_init = build_constructor_single(array_type, range, value);
-
-  return build2(COMPOUND_EXPR, TREE_TYPE(constructor),
-		build2(MODIFY_EXPR, void_type_node,
-		       build_fold_indirect_ref(value_pointer),
-		       space_init),
-		constructor);
+  return gogo->slice_constructor(type_tree, space, length_tree, capacity_tree);
 }
 
 // Return a tree for a pointer to the values in ARRAY.
@@ -5128,16 +4866,6 @@  Map_type::do_get_backend(Gogo* gogo)
   return backend_map_type;
 }
 
-// Initialize a map.
-
-tree
-Map_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
-  if (is_clear)
-    return NULL;
-  return fold_convert(type_tree, null_pointer_node);
-}
-
 // Return an expression for a newly allocated map.
 
 tree
@@ -5374,16 +5102,6 @@  Channel_type::do_get_backend(Gogo* gogo)
   return backend_channel_type;
 }
 
-// Initialize a channel variable.
-
-tree
-Channel_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
-  if (is_clear)
-    return NULL;
-  return fold_convert(type_tree, null_pointer_node);
-}
-
 // Handle the builtin function make for a channel.
 
 tree
@@ -6113,29 +5831,6 @@  Interface_type::do_get_backend(Gogo* gog
     }
 }
 
-// Initialization value.
-
-tree
-Interface_type::do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
-{
-  if (is_clear)
-    return NULL;
-
-  VEC(constructor_elt,gc)* init = VEC_alloc(constructor_elt, gc, 2);
-  for (tree field = TYPE_FIELDS(type_tree);
-       field != NULL_TREE;
-       field = DECL_CHAIN(field))
-    {
-      constructor_elt* elt = VEC_quick_push(constructor_elt, init, NULL);
-      elt->index = field;
-      elt->value = fold_convert(TREE_TYPE(field), null_pointer_node);
-    }
-
-  tree ret = build_constructor(type_tree, init);
-  TREE_CONSTANT(ret) = 1;
-  return ret;
-}
-
 // The type of an interface type descriptor.
 
 Type*
Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc	(revision 174814)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -318,7 +318,10 @@  Expression::convert_type_to_interface(Tr
   // When setting an interface to nil, we just set both fields to
   // NULL.
   if (rhs_type->is_nil_type())
-    return lhs_type->get_init_tree(gogo, false);
+    {
+      Btype* lhs_btype = lhs_type->get_backend(gogo);
+      return expr_to_tree(gogo->backend()->zero_expression(lhs_btype));
+    }
 
   // This should have been checked already.
   go_assert(lhs_interface_type->implements_interface(rhs_type, NULL));
@@ -10046,12 +10049,14 @@  Map_index_expression::do_get_tree(Transl
     }
   else
     {
+      Gogo* gogo = context->gogo();
+      Btype* val_btype = type->val_type()->get_backend(gogo);
+      Bexpression* val_zero = gogo->backend()->zero_expression(val_btype);
       return fold_build3(COND_EXPR, val_type_tree,
 			 fold_build2(EQ_EXPR, boolean_type_node, valptr,
 				     fold_convert(TREE_TYPE(valptr),
 						  null_pointer_node)),
-			 type->val_type()->get_init_tree(context->gogo(),
-							 false),
+			 expr_to_tree(val_zero),
 			 build_fold_indirect_ref(valptr));
     }
 }
@@ -10958,7 +10963,10 @@  Struct_construction_expression::do_get_t
   Gogo* gogo = context->gogo();
 
   if (this->vals_ == NULL)
-    return this->type_->get_init_tree(gogo, false);
+    {
+      Btype* btype = this->type_->get_backend(gogo);
+      return expr_to_tree(gogo->backend()->zero_expression(btype));
+    }
 
   tree type_tree = type_to_tree(this->type_->get_backend(gogo));
   if (type_tree == error_mark_node)
@@ -10977,12 +10985,14 @@  Struct_construction_expression::do_get_t
     {
       go_assert(pf != fields->end());
 
+      Btype* fbtype = pf->type()->get_backend(gogo);
+
       tree val;
       if (pv == this->vals_->end())
-	val = pf->type()->get_init_tree(gogo, false);
+	val = expr_to_tree(gogo->backend()->zero_expression(fbtype));
       else if (*pv == NULL)
 	{
-	  val = pf->type()->get_init_tree(gogo, false);
+	  val = expr_to_tree(gogo->backend()->zero_expression(fbtype));
 	  ++pv;
 	}
       else
@@ -11217,7 +11227,12 @@  Array_construction_expression::get_const
 	  constructor_elt* elt = VEC_quick_push(constructor_elt, values, NULL);
 	  elt->index = size_int(i);
 	  if (*pv == NULL)
-	    elt->value = element_type->get_init_tree(context->gogo(), false);
+	    {
+	      Gogo* gogo = context->gogo();
+	      Btype* ebtype = element_type->get_backend(gogo);
+	      Bexpression *zv = gogo->backend()->zero_expression(ebtype);
+	      elt->value = expr_to_tree(zv);
+	    }
 	  else
 	    {
 	      tree value_tree = (*pv)->get_tree(context);
@@ -11363,7 +11378,9 @@  Open_array_construction_expression::do_g
       VEC(constructor_elt,gc)* vec = VEC_alloc(constructor_elt, gc, 1);
       constructor_elt* elt = VEC_quick_push(constructor_elt, vec, NULL);
       elt->index = size_int(0);
-      elt->value = element_type->get_init_tree(context->gogo(), false);
+      Gogo* gogo = context->gogo();
+      Btype* btype = element_type->get_backend(gogo);
+      elt->value = expr_to_tree(gogo->backend()->zero_expression(btype));
       values = build_constructor(constructor_type, vec);
       if (TREE_CONSTANT(elt->value))
 	TREE_CONSTANT(values) = 1;