From 11075ed893193a415d6b16cd28f06ad4bcc49092 Mon Sep 17 00:00:00 2001 From: Luuk van Dijk Date: Thu, 3 Nov 2011 17:51:15 +0100 Subject: [PATCH] gc: Don't pollute the xmethod list with non-methods. Fixes #2355. I have a test, but not sure if it's worth adding. Instead i've made the patching-over in reflect.c methods more fatal and more descriptive. R=rsc CC=golang-dev https://golang.org/cl/5302082 --- src/cmd/gc/reflect.c | 9 ++++++--- src/cmd/gc/subr.c | 7 +++++-- test/fixedbugs/bug372.go | 28 ++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 test/fixedbugs/bug372.go diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c index 86df3a378d0..d59d1a53977 100644 --- a/src/cmd/gc/reflect.c +++ b/src/cmd/gc/reflect.c @@ -158,10 +158,13 @@ methods(Type *t) // generating code if necessary. a = nil; for(f=mt->xmethod; f; f=f->down) { - if(f->type->etype != TFUNC) - continue; if(f->etype != TFIELD) - fatal("methods: not field"); + fatal("methods: not field %T", f); + if (f->type->etype != TFUNC || f->type->thistuple == 0) + fatal("non-method on %T method %S %T\n", mt, f->sym, f); + if (!getthisx(f->type)->type) + fatal("receiver with no type on %T method %S %T\n", mt, f->sym, f); + method = f->sym; if(method == nil) continue; diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index b12153df34f..11feb61a973 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -2178,8 +2178,11 @@ expandmeth(Sym *s, Type *t) if(c == 0) continue; if(c == 1) { - sl->good = 1; - sl->field = f; + // addot1 may have dug out arbitrary fields, we only want methods. + if(f->type->etype == TFUNC && f->type->thistuple > 0) { + sl->good = 1; + sl->field = f; + } } break; } diff --git a/test/fixedbugs/bug372.go b/test/fixedbugs/bug372.go new file mode 100644 index 00000000000..a6f7208bbd5 --- /dev/null +++ b/test/fixedbugs/bug372.go @@ -0,0 +1,28 @@ +// $G $D/$F.go && $L $F.$A && ./$A.out || echo BUG: bug372 + +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Issue 2355 +package main + +type T struct {} +func (T) m() string { return "T" } + +type TT struct { + T + m func() string +} + + +func ff() string { return "ff" } + +func main() { + var tt TT + tt.m = ff + + if tt.m() != "ff" { + println(tt.m(), "!= \"ff\"") + } +}