[gccgo] Dereference field if necessary to find methods

Submitted by Ian Taylor on Nov. 10, 2010, 10:35 p.m.

Details

Message ID mcrlj50vmb9.fsf@google.com
State New
Headers show

Commit Message

Ian Taylor Nov. 10, 2010, 10:35 p.m.
In Go code like

type S struct {
	i int
}
func (p *S) Get() int {
	return p.i
}
type T struct {
	p **S
}
func f(t *T) int {
	return t.p.Get()
}

gccgo was failing to dereference t.p when looking for the method.  The
dereference is required because selector expressions like t.p
dereference if necessary, and in this case the method is on the type *S
and the field has the type **S.  This patch fixes the problem.
Committed to gccgo branch.

Ian

Patch hide | download patch | download mbox

diff -r a40c51507619 go/types.cc
--- a/go/types.cc	Tue Nov 09 21:53:45 2010 -0800
+++ b/go/types.cc	Wed Nov 10 14:24:04 2010 -0800
@@ -7450,6 +7450,21 @@ 
   const Struct_type* st = type->deref()->struct_type();
   const Interface_type* it = type->deref()->interface_type();
 
+  // If this is a pointer to a pointer, then it is possible that the
+  // pointed-to type has methods.
+  if (nt == NULL
+      && st == NULL
+      && it == NULL
+      && type->points_to() != NULL
+      && type->points_to()->points_to() != NULL)
+    {
+      expr = Expression::make_unary(OPERATOR_MULT, expr, location);
+      type = type->points_to();
+      nt = type->points_to()->named_type();
+      st = type->points_to()->struct_type();
+      it = type->points_to()->interface_type();
+    }
+
   bool receiver_can_be_pointer = (expr->type()->points_to() != NULL
 				  || expr->is_addressable());
   bool is_method = false;