Skip to content

Commit

Permalink
[dev.unified] cmd/compile: fix missing method value wrapper in unifie…
Browse files Browse the repository at this point in the history
…d IR

Unified IR uses to generate wrappers after the global inlining pass, so
it needs to apply inlining for the wrappers itself. However, inlining
may reveal new method value nodes which have not been seen yet, thus
unified IR never generates wrappers for them.

To fix it, just visiting the wrapper function body once more time after
inlining, and generate wrappers for any new method value nodes.

Fixes #52128

Change-Id: I78631c4faa0b00357d4f84704d3525fd38a52cd7
Reviewed-on: https://go-review.googlesource.com/c/go/+/410344
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
  • Loading branch information
cuonglm committed Jun 6, 2022
1 parent 3a1f1e1 commit a8780f9
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/cmd/compile/internal/noder/reader.go
Expand Up @@ -2468,6 +2468,15 @@ func finishWrapperFunc(fn *ir.Func, target *ir.Package) {
// so we're responsible for applying inlining ourselves here.
inline.InlineCalls(fn)

// The body of wrapper function after inlining may reveal new ir.OMETHVALUE node,
// we don't know whether wrapper function has been generated for it or not, so
// generate one immediately here.
ir.VisitList(fn.Body, func(n ir.Node) {
if n, ok := n.(*ir.SelectorExpr); ok && n.Op() == ir.OMETHVALUE {
wrapMethodValue(n.X.Type(), n.Selection, target, true)
}
})

target.Decls = append(target.Decls, fn)
}

Expand Down
21 changes: 21 additions & 0 deletions test/fixedbugs/issue52128.dir/a.go
@@ -0,0 +1,21 @@
// Copyright 2022 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 I interface{}

type F func()

type s struct {
f F
}

func NewWithF(f F) *s {
return &s{f: f}
}

func NewWithFuncI(func() I) *s {
return &s{}
}
17 changes: 17 additions & 0 deletions test/fixedbugs/issue52128.dir/b.go
@@ -0,0 +1,17 @@
// Copyright 2022 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 S struct{}

func (s *S) M1() a.I {
return a.NewWithF(s.M2)
}

func (s *S) M2() {}
14 changes: 14 additions & 0 deletions test/fixedbugs/issue52128.dir/p.go
@@ -0,0 +1,14 @@
// Copyright 2022 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 p

import (
"./a"
"./b"
)

func f() {
a.NewWithFuncI((&b.S{}).M1)
}
7 changes: 7 additions & 0 deletions test/fixedbugs/issue52128.go
@@ -0,0 +1,7 @@
// compiledir

// Copyright 2022 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 ignored

0 comments on commit a8780f9

Please sign in to comment.