diff options
Diffstat (limited to 'test/fixedbugs/issue24693.dir/b.go')
-rw-r--r-- | test/fixedbugs/issue24693.dir/b.go | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/test/fixedbugs/issue24693.dir/b.go b/test/fixedbugs/issue24693.dir/b.go new file mode 100644 index 0000000..15ffa4f --- /dev/null +++ b/test/fixedbugs/issue24693.dir/b.go @@ -0,0 +1,38 @@ +// Copyright 2018 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. + +package b + +import "./a" + +type T struct{ a.T } + +func (T) m() { println("ok") } + +// The compiler used to not pay attention to package for non-exported +// methods when statically constructing itabs. The consequence of this +// was that the call to b.F1(b.T{}) in c.go would create an itab using +// a.T.m instead of b.T.m. +func F1(i interface{ m() }) { i.m() } + +// The interface method calling convention depends on interface method +// sets being sorted in the same order across compilation units. In +// the test case below, at the call to b.F2(b.T{}) in c.go, the +// interface method set is sorted as { a.m(); b.m() }. +// +// However, while compiling package b, its package path is set to "", +// so the code produced for F2 uses { b.m(); a.m() } as the method set +// order. So again, it ends up calling the wrong method. +// +// Also, this function is marked noinline because it's critical to the +// test that the interface method call happen in this compilation +// unit, and the itab construction happens in c.go. +// +//go:noinline +func F2(i interface { + m() + a.I // embeds m() from package a +}) { + i.m() +} |