aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-08-27 22:18:45 -0700
committerIan Lance Taylor <iant@golang.org>2020-09-21 15:53:48 -0700
commit27edc6c3e296a3eea15be291b1f605a647e94107 (patch)
treec6e4455454a14fbbb33edc4c31d941cd9c0797eb /gcc/go
parent1e19ecd79b45af6df87a6869d1936b857c9f71fc (diff)
downloadgcc-27edc6c3e296a3eea15be291b1f605a647e94107.zip
gcc-27edc6c3e296a3eea15be291b1f605a647e94107.tar.gz
gcc-27edc6c3e296a3eea15be291b1f605a647e94107.tar.bz2
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
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc50
-rw-r--r--gcc/go/gofrontend/gogo.cc4
3 files changed, 35 insertions, 21 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index d8db888..e4f8fac 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 8bbc557..0350e51 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 82d4c1f..aef1c47 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)
{