cmd/compile: fix static init for inlined calls

CL 450136 made the compiler to be able to handle simple inlined calls in
staticinit. However, it's missed a condition when checking substituting
arg for param. If there's any non-trivial closures, it has captured one
of the param, so the substitution could not happen.

Fixes #56778

Change-Id: I427c9134e333e2f9af136c1a124da4d37d326f10
Reviewed-on: https://go-review.googlesource.com/c/go/+/451555
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Cuong Manh Le 2022-11-17 19:21:45 +07:00 committed by Gopher Robot
parent 217ed95588
commit 249e51e5d9
4 changed files with 46 additions and 0 deletions

View file

@ -570,13 +570,25 @@ func (s *Schedule) staticAssignInlinedCall(l *ir.Name, loff int64, call *ir.Inli
for _, x := range as2init.Lhs {
count[x.(*ir.Name)] = 0
}
hasNonTrivialClosure := false
ir.Visit(as2body.Rhs[0], func(n ir.Node) {
if name, ok := n.(*ir.Name); ok {
if c, ok := count[name]; ok {
count[name] = c + 1
}
}
if clo, ok := n.(*ir.ClosureExpr); ok {
hasNonTrivialClosure = hasNonTrivialClosure || !ir.IsTrivialClosure(clo)
}
})
// If there's a non-trivial closure, it has captured the param,
// so we can't substitute arg for param.
if hasNonTrivialClosure {
return false
}
for name, c := range count {
if c > 1 {
// Check whether corresponding initializer can be repeated.

View file

@ -0,0 +1,18 @@
// 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 A struct {
New func() any
}
func NewA(i int) *A {
return &A{
New: func() any {
_ = i
return nil
},
}
}

View file

@ -0,0 +1,9 @@
// 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"
var _ = a.NewA(0)

View file

@ -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