cmd/compile/internal/gc: mark generated wrappers as DUPOK

Interface wrapper functions now get compiled eagerly in some cases.
Consequently, they may be present in multiple translation units.
Mark them as DUPOK, just like closures.

Fixes #19548
Fixes #19550

Change-Id: Ibe74adb5a62dbf6447db37fde22dcbb3479969ef
Reviewed-on: https://go-review.googlesource.com/38156
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Philip Hofer 2017-03-14 14:00:38 -07:00 committed by David Chase
parent 8a44c8efae
commit 710f4d3e7e
4 changed files with 60 additions and 0 deletions

View file

@ -1711,6 +1711,7 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
t.Rlist.Set(out)
fn := nod(ODCLFUNC, nil, nil)
fn.Func.SetDupok(true)
fn.Func.Nname = newname(newnam)
fn.Func.Nname.Name.Defn = fn
fn.Func.Nname.Name.Param.Ntype = t

View file

@ -0,0 +1,26 @@
// 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
type Mode uint
func (m Mode) String() string { return "mode string" }
func (m *Mode) Addr() *Mode { return m }
type Stringer interface {
String() string
}
var global Stringer
var m Mode
func init() {
// force compilation of the (*Mode).String() wrapper
global = &m
}
func String() string {
return global.String() + Mode(0).String()
}

View file

@ -0,0 +1,24 @@
// 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
import "./a"
type Value interface {
a.Stringer
Addr() *a.Mode
}
var global a.Mode
func f() int {
var v Value
v = &global
return int(v.String()[0])
}
func main() {
f()
}

View file

@ -0,0 +1,9 @@
// rundir
// Copyright 2017 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.
// Test that interface wrappers can be compiled successfully
// in multiple translation units.
package ignore