Skip to content

Commit 9a555fc

Browse files
committed
cmd/compile: fix missing descend in Addrtaken for closures.
ComputeAddrtaken needs to descend into closures, now that imported bodies can include closures. The bug was that we weren't properly setting Addrtaken for a variable inside a closure inside a function that we were importing. For now, still disable inlining of functions with closures for -G mode. I'll enable it in a later change -- there are just a few fixes related to the fact that we don't need to set Ntype for closure functions. Added a test derived from the cilium repro in the issue. Fixes #44370 Change-Id: Ida2a403636bf8740b471b3ad68b5474951811e19 Reviewed-on: https://go-review.googlesource.com/c/go/+/296649 Run-TryBot: Dan Scales <[email protected]> Trust: Dan Scales <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
1 parent a61524d commit 9a555fc

File tree

6 files changed

+47
-5
lines changed

6 files changed

+47
-5
lines changed

src/cmd/compile/internal/base/flag.go

+1
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ func ParseFlags() {
159159
Flag.LinkShared = &Ctxt.Flag_linkshared
160160
Flag.Shared = &Ctxt.Flag_shared
161161
Flag.WB = true
162+
Debug.InlFuncsWithClosures = 1
162163

163164
Flag.Cfg.ImportMap = make(map[string]string)
164165

src/cmd/compile/internal/inline/inl.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,7 @@ func (v *hairyVisitor) doNode(n ir.Node) bool {
354354
return true
355355

356356
case ir.OCLOSURE:
357-
if base.Debug.InlFuncsWithClosures == 0 {
358-
// TODO(danscales): change default of InlFuncsWithClosures
359-
// to 1 when #44370 is fixed
357+
if base.Debug.InlFuncsWithClosures == 0 || base.Flag.G > 0 {
360358
v.reason = "not inlining functions with closures"
361359
return true
362360
}

src/cmd/compile/internal/typecheck/subr.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ var DirtyAddrtaken = false
106106

107107
func ComputeAddrtaken(top []ir.Node) {
108108
for _, n := range top {
109-
ir.Visit(n, func(n ir.Node) {
109+
var doVisit func(n ir.Node)
110+
doVisit = func(n ir.Node) {
110111
if n.Op() == ir.OADDR {
111112
if x := ir.OuterValue(n.(*ir.AddrExpr).X); x.Op() == ir.ONAME {
112113
x.Name().SetAddrtaken(true)
@@ -117,7 +118,11 @@ func ComputeAddrtaken(top []ir.Node) {
117118
}
118119
}
119120
}
120-
})
121+
if n.Op() == ir.OCLOSURE {
122+
ir.VisitList(n.(*ir.ClosureExpr).Func.Body, doVisit)
123+
}
124+
}
125+
ir.Visit(n, doVisit)
121126
}
122127
}
123128

test/fixedbugs/issue44370.dir/a.go

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2021 The Go Authors. All rights reserved. Use of this
2+
// source code is governed by a BSD-style license that can be found in
3+
// the LICENSE file.
4+
5+
package a
6+
7+
// A StoppableWaitGroup waits for a collection of goroutines to finish.
8+
type StoppableWaitGroup struct {
9+
// i is the internal counter which can store tolerate negative values
10+
// as opposed the golang's library WaitGroup.
11+
i *int64
12+
}
13+
14+
// NewStoppableWaitGroup returns a new StoppableWaitGroup. When the 'Stop' is
15+
// executed, following 'Add()' calls won't have any effect.
16+
func NewStoppableWaitGroup() *StoppableWaitGroup {
17+
return &StoppableWaitGroup{
18+
i: func() *int64 { i := int64(0); return &i }(),
19+
}
20+
}

test/fixedbugs/issue44370.dir/b.go

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2021 The Go Authors. All rights reserved. Use of this
2+
// source code is governed by a BSD-style license that can be found in
3+
// the LICENSE file.
4+
5+
package b
6+
7+
import "./a"
8+
9+
func JoinClusterServices() {
10+
_ = a.NewStoppableWaitGroup()
11+
}

test/fixedbugs/issue44370.go

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// compiledir
2+
3+
// Copyright 2021 The Go Authors. All rights reserved. Use of this
4+
// source code is governed by a BSD-style license that can be found in
5+
// the LICENSE file.
6+
7+
package ignored

0 commit comments

Comments
 (0)