diff mbox series

Go patch committed: Handle value method of direct interface type

Message ID CAOyqgcVGUpxnqDBvns1uJB1_o6Ux3g=sA7_GwAZvtZ=qM51nKg@mail.gmail.com
State New
Headers show
Series Go patch committed: Handle value method of direct interface type | expand

Commit Message

Ian Lance Taylor May 8, 2019, 4:29 a.m. UTC
This patch to the Go frontend by Cherry Zhang avoids using a double
pointer for the value method of a 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.  A test case for this can be found in
https://golang.org/cl/175880.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
diff mbox series

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 270993)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -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.
Index: gcc/go/gofrontend/types.cc
===================================================================
--- gcc/go/gofrontend/types.cc	(revision 270877)
+++ gcc/go/gofrontend/types.cc	(working copy)
@@ -3440,14 +3440,15 @@  Type::method_constructor(Gogo*, Type* me
       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* me
 
   ++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));