diff options
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) { |