]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: mark wrapper methods for unnamed types as DUPOK.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Wed, 2 Jan 2013 20:42:26 +0000 (21:42 +0100)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Wed, 2 Jan 2013 20:42:26 +0000 (21:42 +0100)
Unnamed types like structs with embedded fields can have methods.
These methods are generated on-the-fly by the compiler and
it may happen for identical types in different packages.
The linker must accept these multiple definitions.

Fixes #4590.

R=golang-dev, rsc
CC=golang-dev, remy
https://golang.org/cl/7030051

src/cmd/gc/subr.c
test/fixedbugs/issue4590.dir/pkg1.go [new file with mode: 0644]
test/fixedbugs/issue4590.dir/pkg2.go [new file with mode: 0644]
test/fixedbugs/issue4590.dir/prog.go [new file with mode: 0644]
test/fixedbugs/issue4590.go [new file with mode: 0644]

index e42feab3be77bebf1fa7bb9c40dc261097fc4e0b..674c49bc03af1378de849371d474b134eff32161 100644 (file)
@@ -2521,6 +2521,9 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
 
        funcbody(fn);
        curfn = fn;
+       // wrappers where T is anonymous (struct{ NamedType }) can be duplicated.
+       if(rcvr->etype == TSTRUCT || isptr[rcvr->etype] && rcvr->type->etype == TSTRUCT)
+               fn->dupok = 1;
        typecheck(&fn, Etop);
        typechecklist(fn->nbody, Etop);
        curfn = nil;
diff --git a/test/fixedbugs/issue4590.dir/pkg1.go b/test/fixedbugs/issue4590.dir/pkg1.go
new file mode 100644 (file)
index 0000000..c447371
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2012 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 pkg1
+
+type A interface {
+       Write() error
+}
+
+type B interface {
+       Hello()
+       world()
+}
+
+type C struct{}
+
+func (c C) Write() error { return nil }
+
+var T = struct{ A }{nil}
+var U = struct{ B }{nil}
+var V A = struct{ *C }{nil}
+var W = interface {
+       Write() error
+       Hello()
+}(nil)
diff --git a/test/fixedbugs/issue4590.dir/pkg2.go b/test/fixedbugs/issue4590.dir/pkg2.go
new file mode 100644 (file)
index 0000000..61c01d7
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2012 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 pkg2
+
+import "./pkg1"
+
+var T = struct{ pkg1.A }{nil}
+var U = struct{ pkg1.B }{nil}
+var V pkg1.A = struct{ *pkg1.C }{nil}
+var W = interface {
+       Write() error
+       Hello()
+}(nil)
diff --git a/test/fixedbugs/issue4590.dir/prog.go b/test/fixedbugs/issue4590.dir/prog.go
new file mode 100644 (file)
index 0000000..3220e85
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2012 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
+
+import (
+       "./pkg1"
+       "./pkg2"
+)
+
+func main() {
+       if pkg1.T != pkg2.T {
+               panic("pkg1.T != pkg2.T")
+       }
+       if pkg1.U != pkg2.U {
+               panic("pkg1.U != pkg2.U")
+       }
+       if pkg1.V != pkg2.V {
+               panic("pkg1.V != pkg2.V")
+       }
+       if pkg1.W != pkg2.W {
+               panic("pkg1.W != pkg2.W")
+       }
+}
diff --git a/test/fixedbugs/issue4590.go b/test/fixedbugs/issue4590.go
new file mode 100644 (file)
index 0000000..faeb1ad
--- /dev/null
@@ -0,0 +1,10 @@
+// rundir
+
+// Copyright 2012 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 4590: linker fails on multiple imports of
+// an anonymous struct with methods.
+
+package ignored