]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix parsing of inlined interface types with unexported methods
authorRobert Griesemer <gri@golang.org>
Sat, 30 Jan 2016 22:29:02 +0000 (14:29 -0800)
committerRobert Griesemer <gri@golang.org>
Mon, 1 Feb 2016 20:29:19 +0000 (20:29 +0000)
Fixes #14164.

Change-Id: Ib1d1d29674c99cf88e0ae12724823a31f5dbb95c
Reviewed-on: https://go-review.googlesource.com/19087
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/compile/internal/gc/parser.go
test/fixedbugs/issue14164.dir/a.go [new file with mode: 0644]
test/fixedbugs/issue14164.dir/main.go [new file with mode: 0644]
test/fixedbugs/issue14164.go [new file with mode: 0644]

index 282e855b37eacf4ba16c0c7a1d8917f0c19ef947..054cf7365617ce662a5b9b244c1c751900f95a0d 100644 (file)
@@ -2501,6 +2501,24 @@ func (p *parser) interfacedcl() *Node {
                ifacedcl(meth)
                return meth
 
+       case '@', '?':
+               // newname indcl
+               // We arrive here when parsing an interface type declared inside
+               // an exported and inlineable function and the interface declares
+               // unexported methods (which are then package-qualified).
+               //
+               // Since the compiler always flattens embedded interfaces, we
+               // will never see an embedded package-qualified interface in export
+               // data; i.e., when we reach here we know it must be a method.
+               //
+               // See also issue 14164.
+               mname := newname(p.sym())
+               sig := p.indcl()
+
+               meth := Nod(ODCLFIELD, mname, sig)
+               ifacedcl(meth)
+               return meth
+
        case '(':
                p.next()
                pname := p.packname(nil)
diff --git a/test/fixedbugs/issue14164.dir/a.go b/test/fixedbugs/issue14164.dir/a.go
new file mode 100644 (file)
index 0000000..bf03051
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2016 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 a
+
+// F is an exported function, small enough to be inlined.
+// It defines a local interface with an unexported method
+// f, which will appear with a package-qualified method
+// name in the export data.
+func F(x interface{}) bool {
+       _, ok := x.(interface {
+               f()
+       })
+       return ok
+}
+
+// Like F but with the unexported interface method f
+// defined via an embedded interface t. The compiler
+// always flattens embedded interfaces so there should
+// be no difference between F and G. Alas, currently
+// G is not inlineable (at least via export data), so
+// the issue is moot, here.
+func G(x interface{}) bool {
+       type t0 interface {
+               f()
+       }
+       _, ok := x.(interface {
+               t0
+       })
+       return ok
+}
+
+// Like G but now the embedded interface is declared
+// at package level. This function is inlineable via
+// export data. The export data representation is like
+// for F.
+func H(x interface{}) bool {
+       _, ok := x.(interface {
+               t1
+       })
+       return ok
+}
+
+type t1 interface {
+       f()
+}
diff --git a/test/fixedbugs/issue14164.dir/main.go b/test/fixedbugs/issue14164.dir/main.go
new file mode 100644 (file)
index 0000000..bcc6a63
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2016 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 main
+
+// Verify that we can import package "a" containing an inlineable
+// function F that declares a local interface with a non-exported
+// method f.
+import _ "./a"
+
+func main() {}
diff --git a/test/fixedbugs/issue14164.go b/test/fixedbugs/issue14164.go
new file mode 100644 (file)
index 0000000..5247599
--- /dev/null
@@ -0,0 +1,7 @@
+// compiledir
+
+// Copyright 2016 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.
+
+ignored