[gcc r11-3342] compiler: finalize methods for type aliases of struct types
Ian Lance Taylor
ian@gcc.gnu.org
Mon Sep 21 22:54:03 GMT 2020
https://gcc.gnu.org/g:27edc6c3e296a3eea15be291b1f605a647e94107
commit r11-3342-g27edc6c3e296a3eea15be291b1f605a647e94107
Author: Ian Lance Taylor <iant@golang.org>
Date: Thu Aug 27 22:18:45 2020 -0700
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
Diff:
---
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)
{
More information about the Gcc-cvs
mailing list