From 5a815b930afa24b49723919b0e7da0bd04028d28 Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor <ian@gcc.gnu.org>
Date: Fri, 17 Feb 2012 20:00:34 +0000
Subject: [PATCH] compiler: Fix backend representation for interface methods.

From-SVN: r184348
---
 gcc/go/gofrontend/types.cc | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 61ec555cc548..4ed54bb53587 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -6886,10 +6886,37 @@ get_backend_interface_fields(Gogo* gogo, Interface_type* type,
        p != type->methods()->end();
        ++p, ++i)
     {
+      // The type of the method in Go only includes the parameters.
+      // The actual method also has a receiver, which is always a
+      // pointer.  We need to add that pointer type here in order to
+      // generate the correct type for the backend.
+      Function_type* ft = p->type()->function_type();
+      go_assert(ft->receiver() == NULL);
+
+      const Typed_identifier_list* params = ft->parameters();
+      Typed_identifier_list* mparams = new Typed_identifier_list();
+      if (params != NULL)
+	mparams->reserve(params->size() + 1);
+      Type* vt = Type::make_pointer_type(Type::make_void_type());
+      mparams->push_back(Typed_identifier("", vt, ft->location()));
+      if (params != NULL)
+	{
+	  for (Typed_identifier_list::const_iterator pp = params->begin();
+	       pp != params->end();
+	       ++pp)
+	    mparams->push_back(*pp);
+	}
+
+      Typed_identifier_list* mresults = (ft->results() == NULL
+					 ? NULL
+					 : ft->results()->copy());
+      Function_type* mft = Type::make_function_type(NULL, mparams, mresults,
+						    ft->location());
+
       mfields[i].name = Gogo::unpack_hidden_name(p->name());
       mfields[i].btype = (use_placeholder
-			  ? p->type()->get_backend_placeholder(gogo)
-			  : p->type()->get_backend(gogo));
+			  ? mft->get_backend_placeholder(gogo)
+			  : mft->get_backend(gogo));
       mfields[i].location = loc;
       // Sanity check: the names should be sorted.
       go_assert(p->name() > last_name);
-- 
GitLab