Rewrite conversion of named types to backend representation.
[gcc.git] / gcc / go / gofrontend / expressions.cc
index 2e31e8064785f30fd1e7605bf46a6c95ff55af78..ee486ffb27a79d5b3107e7a1785b05ad25774330 100644 (file)
@@ -7013,6 +7013,8 @@ Builtin_call_expression::do_integer_constant_value(bool iota_is_constant,
        return false;
       if (arg_type->is_abstract())
        return false;
+      if (arg_type->named_type() != NULL)
+       arg_type->named_type()->convert(this->gogo_);
       tree arg_type_tree = arg_type->get_tree(this->gogo_);
       if (arg_type_tree == error_mark_node)
        return false;
@@ -7057,6 +7059,8 @@ Builtin_call_expression::do_integer_constant_value(bool iota_is_constant,
       Type* st = struct_expr->type();
       if (st->struct_type() == NULL)
        return false;
+      if (st->named_type() != NULL)
+       st->named_type()->convert(this->gogo_);
       tree struct_tree = st->get_tree(this->gogo_);
       gcc_assert(TREE_CODE(struct_tree) == RECORD_TYPE);
       tree field = TYPE_FIELDS(struct_tree);
@@ -8281,8 +8285,9 @@ Call_expression::do_lower(Gogo* gogo, Named_object* function, int)
          for (size_t i = 0; i < rc; ++i)
            args->push_back(Expression::make_call_result(call, i));
          // We can't return a new call expression here, because this
-         // one may be referenced by Call_result expressions.  FIXME.
-         delete this->args_;
+         // one may be referenced by Call_result expressions.  We
+         // also can't delete the old arguments, because we may still
+         // traverse them somewhere up the call stack.  FIXME.
          this->args_ = args;
        }
     }
@@ -8792,10 +8797,21 @@ Call_expression::do_get_tree(Translate_context* context)
       return error_mark_node;
     }
 
-  // This is to support builtin math functions when using 80387 math.
   tree fndecl = fn;
   if (TREE_CODE(fndecl) == ADDR_EXPR)
     fndecl = TREE_OPERAND(fndecl, 0);
+
+  // Add a type cast in case the type of the function is a recursive
+  // type which refers to itself.
+  if (!DECL_P(fndecl) || !DECL_IS_BUILTIN(fndecl))
+    {
+      tree fnt = fntype->get_tree(gogo);
+      if (fnt == error_mark_node)
+       return error_mark_node;
+      fn = fold_convert_loc(location, fnt, fn);
+    }
+
+  // This is to support builtin math functions when using 80387 math.
   tree excess_type = NULL_TREE;
   if (DECL_P(fndecl)
       && DECL_IS_BUILTIN(fndecl)
@@ -8841,7 +8857,7 @@ Call_expression::do_get_tree(Translate_context* context)
   // to the correct type.
   if (TREE_TYPE(ret) == ptr_type_node)
     {
-      tree t = this->type()->get_tree(gogo);
+      tree t = this->type()->base()->get_tree(gogo);
       ret = fold_convert_loc(location, t, ret);
     }
 
@@ -12264,7 +12280,11 @@ tree
 Receive_expression::do_get_tree(Translate_context* context)
 {
   Channel_type* channel_type = this->channel_->type()->channel_type();
-  gcc_assert(channel_type != NULL);
+  if (channel_type == NULL)
+    {
+      gcc_assert(this->channel_->type()->is_error_type());
+      return error_mark_node;
+    }
   Type* element_type = channel_type->element_type();
   tree element_type_tree = element_type->get_tree(context->gogo());