summaryrefslogtreecommitdiffstats
path: root/test/fixedbugs/issue24693.dir/b.go
diff options
context:
space:
mode:
Diffstat (limited to 'test/fixedbugs/issue24693.dir/b.go')
-rw-r--r--test/fixedbugs/issue24693.dir/b.go38
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()
+}