diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 61ec555cc54803aed752ea59325e069b40e9a832..4ed54bb535870b9f866adc0b997d7a340e30e699 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);