From 27edc6c3e296a3eea15be291b1f605a647e94107 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 27 Aug 2020 22:18:45 -0700 Subject: [PATCH] compiler: finalize methods for type aliases of struct types Previously we would finalize the methods of the alias type itself, but since its a type alias we really need to finalize the methods of the aliased type. Also, handle method expressions of unnamed struct types. Test case is https://golang.org/cl/251168. Fixes golang/go#38125 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/251279 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 50 +++++++++++++++++++------------- gcc/go/gofrontend/gogo.cc | 4 +++ 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index d8db888e4b6..e4f8fac5ab3 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -6f309797e4f7eed635950687e902a294126e6fc6 +a59167c29d6ad2ddf533b3a12b365f72df0e1476 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 8bbc557c65f..0350e51d3a6 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -14529,21 +14529,19 @@ Selector_expression::lower_method_expression(Gogo* gogo) is_pointer = true; type = type->points_to(); } - Named_type* nt = type->named_type(); - if (nt == NULL) - { - go_error_at(location, - ("method expression requires named type or " - "pointer to named type")); - return Expression::make_error(location); - } + Named_type* nt = type->named_type(); + Struct_type* st = type->struct_type(); bool is_ambiguous; - Method* method = nt->method_function(name, &is_ambiguous); + Method* method = NULL; + if (nt != NULL) + method = nt->method_function(name, &is_ambiguous); + else if (st != NULL) + method = st->method_function(name, &is_ambiguous); const Typed_identifier* imethod = NULL; if (method == NULL && !is_pointer) { - Interface_type* it = nt->interface_type(); + Interface_type* it = type->interface_type(); if (it != NULL) imethod = it->find_method(name); } @@ -14551,16 +14549,28 @@ Selector_expression::lower_method_expression(Gogo* gogo) if ((method == NULL && imethod == NULL) || (left_type->named_type() != NULL && left_type->points_to() != NULL)) { - if (!is_ambiguous) - go_error_at(location, "type %<%s%s%> has no method %<%s%>", - is_pointer ? "*" : "", - nt->message_name().c_str(), - Gogo::message_name(name).c_str()); + if (nt != NULL) + { + if (!is_ambiguous) + go_error_at(location, "type %<%s%s%> has no method %<%s%>", + is_pointer ? "*" : "", + nt->message_name().c_str(), + Gogo::message_name(name).c_str()); + else + go_error_at(location, "method %<%s%s%> is ambiguous in type %<%s%>", + Gogo::message_name(name).c_str(), + is_pointer ? "*" : "", + nt->message_name().c_str()); + } else - go_error_at(location, "method %<%s%s%> is ambiguous in type %<%s%>", - Gogo::message_name(name).c_str(), - is_pointer ? "*" : "", - nt->message_name().c_str()); + { + if (!is_ambiguous) + go_error_at(location, "type has no method %<%s%>", + Gogo::message_name(name).c_str()); + else + go_error_at(location, "method %<%s%> is ambiguous", + Gogo::message_name(name).c_str()); + } return Expression::make_error(location); } @@ -14657,7 +14667,7 @@ Selector_expression::lower_method_expression(Gogo* gogo) Expression* ve = Expression::make_var_reference(vno, location); Expression* bm; if (method != NULL) - bm = Type::bind_field_or_method(gogo, nt, ve, name, location); + bm = Type::bind_field_or_method(gogo, type, ve, name, location); else bm = Expression::make_interface_field_reference(ve, name, location); diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 82d4c1fd54d..aef1c47d26e 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -3508,6 +3508,10 @@ Finalize_methods::type(Type* t) case Type::TYPE_NAMED: { Named_type* nt = t->named_type(); + + if (nt->is_alias()) + return TRAVERSE_CONTINUE; + Type* rt = nt->real_type(); if (rt->classification() != Type::TYPE_STRUCT) { -- 2.30.2