diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-05-08 04:29:46 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-05-08 04:29:46 +0000 |
commit | d9b120ce89f7198d1a82727f54e0563321a2cba8 (patch) | |
tree | bd930ed9851577570d81bfd24c362fca225da645 | |
parent | 8c4a4099743ad6040f88252ac99962503ddede3d (diff) | |
download | gcc-d9b120ce89f7198d1a82727f54e0563321a2cba8.zip gcc-d9b120ce89f7198d1a82727f54e0563321a2cba8.tar.gz gcc-d9b120ce89f7198d1a82727f54e0563321a2cba8.tar.bz2 |
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
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 20 |
2 files changed, 12 insertions, 10 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index aafb52c..ed95dfd 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -dc9c1b43753f392fdc2045bcb7a4abaa44fe79f1 +e3ba8828baf60343316bb68002e94570ee63ad1e 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/types.cc b/gcc/go/gofrontend/types.cc index 5796d2d..371b65f 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -3440,14 +3440,15 @@ Type::method_constructor(Gogo*, Type* method_type, vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc)); } - Named_object* no = - ((this->points_to() != NULL - && this->points_to()->is_direct_iface_type() - && m->is_value_method()) - ? m->iface_stub_object() - : (m->needs_stub_method() - ? m->stub_object() - : m->named_object())); + bool use_direct_iface_stub = + this->points_to() != NULL + && this->points_to()->is_direct_iface_type() + && m->is_value_method(); + Named_object* no = (use_direct_iface_stub + ? m->iface_stub_object() + : (m->needs_stub_method() + ? m->stub_object() + : m->named_object())); Function_type* mtype; if (no->is_function()) @@ -3463,7 +3464,8 @@ Type::method_constructor(Gogo*, Type* method_type, ++p; 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); vals->push_back(Expression::make_type_descriptor(nonmethod_type, bloc)); |