Commit d9b120ce by Ian Lance Taylor

compiler: don't add pointer twice to value method of direct interface type

    
    For a direct interface type T with a value method M, its pointer
    type (*T)'s method table includes a stub method of M which takes
    a (*T) as the receiver instead of a T. However, for the "typ"
    field of the method table entry, we added another layer of
    indirection, which makes it appear to take a **T, which is wrong.
    This causes problems when using reflect.Type.Method to get the
    method. This CL fixes the second, incorrect, indirection.
    
    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/175837

From-SVN: r270999
parent 8c4a4099
dc9c1b43753f392fdc2045bcb7a4abaa44fe79f1 e3ba8828baf60343316bb68002e94570ee63ad1e
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -3440,14 +3440,15 @@ Type::method_constructor(Gogo*, Type* method_type, ...@@ -3440,14 +3440,15 @@ Type::method_constructor(Gogo*, Type* method_type,
vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc)); vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
} }
Named_object* no = bool use_direct_iface_stub =
((this->points_to() != NULL this->points_to() != NULL
&& this->points_to()->is_direct_iface_type() && this->points_to()->is_direct_iface_type()
&& m->is_value_method()) && m->is_value_method();
? m->iface_stub_object() Named_object* no = (use_direct_iface_stub
: (m->needs_stub_method() ? m->iface_stub_object()
? m->stub_object() : (m->needs_stub_method()
: m->named_object())); ? m->stub_object()
: m->named_object()));
Function_type* mtype; Function_type* mtype;
if (no->is_function()) if (no->is_function())
...@@ -3463,7 +3464,8 @@ Type::method_constructor(Gogo*, Type* method_type, ...@@ -3463,7 +3464,8 @@ Type::method_constructor(Gogo*, Type* method_type,
++p; ++p;
go_assert(p->is_field_name("typ")); go_assert(p->is_field_name("typ"));
bool want_pointer_receiver = !only_value_methods && m->is_value_method(); bool want_pointer_receiver = (!only_value_methods && m->is_value_method()
&& !use_direct_iface_stub);
nonmethod_type = mtype->copy_with_receiver_as_param(want_pointer_receiver); nonmethod_type = mtype->copy_with_receiver_as_param(want_pointer_receiver);
vals->push_back(Expression::make_type_descriptor(nonmethod_type, bloc)); vals->push_back(Expression::make_type_descriptor(nonmethod_type, bloc));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment