mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
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:
parent
217ed95588
commit
249e51e5d9
@ -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.
|
||||
|
18
test/fixedbugs/issue56778.dir/a.go
Normal file
18
test/fixedbugs/issue56778.dir/a.go
Normal 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
|
||||
},
|
||||
}
|
||||
}
|
9
test/fixedbugs/issue56778.dir/b.go
Normal file
9
test/fixedbugs/issue56778.dir/b.go
Normal 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)
|
7
test/fixedbugs/issue56778.go
Normal file
7
test/fixedbugs/issue56778.go
Normal 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
|
Loading…
x
Reference in New Issue
Block a user