Skip to content

Commit ce4fc94

Browse files
committed
cmd/compile: use inline tree index to identify call stack
When building the name for closures, in order to make sure each closure has a unique name, we attach a hash of the inline call stack. We currently use a combination of function name, line number, and column number at each level to construct the hash. In some situations, this may not be able to uniquely identify the call stack: there could be multiple inline call sites at the same line of different files (we currently don't include the file name), and XPos.ColumnNumber can saturate. This could lead to duplicate symbol definitions. Instead of using name + line number + column number, switch to use the global inline tree index, which should uniquely identify the call site at each level. Fixes golang#79274. Change-Id: I69110a212d6b856283aae4c999258ae585be5977 Reviewed-on: https://go-review.googlesource.com/c/go/+/775624 Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
1 parent 55ff407 commit ce4fc94

5 files changed

Lines changed: 48 additions & 3 deletions

File tree

src/cmd/compile/internal/ir/func.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"cmd/internal/src"
1414
"encoding/base64"
1515
"fmt"
16-
"io"
1716
"unicode/utf8"
1817
)
1918

@@ -472,9 +471,11 @@ func closureName(outerfn *Func, pos src.XPos, why Op, gen int) *types.Sym {
472471
// we use a content hash to disambiguate instead.
473472
// We choose the suffix as a hash of the inline call stack.
474473
h := hash.New32()
475-
io.WriteString(h, outer)
474+
fmt.Fprint(h, inlIndex)
476475
base.Ctxt.InlTree.AllParents(inlIndex, func(call obj.InlinedCall) {
477-
io.WriteString(h, call.Name+":"+call.Pos.LineNumber()+":"+call.Pos.ColumnNumber())
476+
if call.Parent >= 0 {
477+
fmt.Fprint(h, " ", call.Parent)
478+
}
478479
})
479480
inlHash = base64.StdEncoding.EncodeToString(h.Sum(nil)[:8])
480481

test/fixedbugs/issue79274.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// compile
2+
3+
// Copyright 2026 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package main
8+
9+
import "math/big"
10+
11+
func F() {
12+
var pg0_0 *int
13+
_ = pg0_0
14+
var u16_0 uint16
15+
fnc := func(a [0][][3]int, b [14][9]uint16, c []big.Int) uint16 {
16+
pg0_0 = func() *int { return nil }()
17+
return 0
18+
}
19+
20+
fnc([0][][3]int{}, [14][9]uint16{[9]uint16{fnc([0][][3]int{}, [14][9]uint16{[9]uint16{min(fnc([0][][3]int{}, [14][9]uint16{[9]uint16{(uint16)(16), (uint16)(93), (uint16)(31)}, [9]uint16{(uint16)(5), (uint16)(69)}, [9]uint16{}}, []big.Int{}), u16_0), fnc([0][][3]int{}, [14][9]uint16{}, nil)}, [9]uint16{fnc([0][][3]int{}, [14][9]uint16{}, nil)}, [9]uint16{}}, nil), 0}}, nil)
21+
}
22+
23+
func main() {
24+
F()
25+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright 2026 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package p
6+
var _ = F(); func F() func() { return func() {} }
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright 2026 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package p
6+
var _ = F()

test/fixedbugs/issue79274a.go

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

0 commit comments

Comments
 (0)