]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: ensure deterministic output when reporting an init cycle
authorWingrez <31106425+wingrez@users.noreply.github.com>
Fri, 17 Jan 2025 00:38:59 +0000 (00:38 +0000)
committerGopher Robot <gobot@golang.org>
Fri, 17 Jan 2025 16:22:41 +0000 (08:22 -0800)
Fixes #71254

Change-Id: Ie3bad281403c8ff6215e03d92760b9a378714cee
GitHub-Last-Rev: 9b804a7842421dca6a97c57ce18523b593b0817d
GitHub-Pull-Request: golang/go#71264
Reviewed-on: https://go-review.googlesource.com/c/go/+/642396
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>

src/cmd/compile/internal/types2/initorder.go
src/cmd/compile/internal/types2/testdata/local/issue71254.go [new file with mode: 0644]
src/go/types/initorder.go

index ef2ad010a6d5fb80bc0bff2a6686f05a69226f6a..699bfca8bbc895a1f966af307e477142810022ae 100644 (file)
@@ -10,6 +10,7 @@ import (
        "fmt"
        . "internal/types/errors"
        "slices"
+       "sort"
 )
 
 // initOrder computes the Info.InitOrder for package variables.
@@ -139,7 +140,16 @@ func findPath(objMap map[Object]*declInfo, from, to Object, seen map[Object]bool
        }
        seen[from] = true
 
+       // sort deps for deterministic result
+       var deps []Object
        for d := range objMap[from].deps {
+               deps = append(deps, d)
+       }
+       sort.Slice(deps, func(i, j int) bool {
+               return deps[i].order() < deps[j].order()
+       })
+
+       for _, d := range deps {
                if d == to {
                        return []Object{d}
                }
diff --git a/src/cmd/compile/internal/types2/testdata/local/issue71254.go b/src/cmd/compile/internal/types2/testdata/local/issue71254.go
new file mode 100644 (file)
index 0000000..9cca9d5
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2025 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
+
+const (
+       B /* ERROR "initialization cycle: B refers to itself" */ = A + B
+       A /* ERRORx "initialization cycle for A\\s+.*A refers to B\\s+.*B refers to A" */ = A + B
+
+       C /* ERRORx "initialization cycle for C\\s+.*C refers to D\\s+.*D refers to C" */ = E + D
+       D /* ERRORx "initialization cycle for D\\s+.*D refers to C\\s+.*C refers to D" */ = E + C
+       E = D + C
+)
index 7625c20667499435b96899318fa38fc4a4f4461d..adf96fe718f13d27906eff4dfd66a5a74ad4440c 100644 (file)
@@ -13,6 +13,7 @@ import (
        "fmt"
        . "internal/types/errors"
        "slices"
+       "sort"
 )
 
 // initOrder computes the Info.InitOrder for package variables.
@@ -142,7 +143,16 @@ func findPath(objMap map[Object]*declInfo, from, to Object, seen map[Object]bool
        }
        seen[from] = true
 
+       // sort deps for deterministic result
+       var deps []Object
        for d := range objMap[from].deps {
+               deps = append(deps, d)
+       }
+       sort.Slice(deps, func(i, j int) bool {
+               return deps[i].order() < deps[j].order()
+       })
+
+       for _, d := range deps {
                if d == to {
                        return []Object{d}
                }