diff options
author | Ian Lance Taylor <iant@golang.org> | 2020-08-27 22:18:45 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2020-09-21 15:53:48 -0700 |
commit | 27edc6c3e296a3eea15be291b1f605a647e94107 (patch) | |
tree | c6e4455454a14fbbb33edc4c31d941cd9c0797eb /gcc/go | |
parent | 1e19ecd79b45af6df87a6869d1936b857c9f71fc (diff) | |
download | gcc-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/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 50 | ||||
-rw-r--r-- | 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 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) { |