First, remove the randomization of initialization order.
Then, revert to source code order instead of sorted package path order.
This restores the behavior that was in 1.12.
A larger change which will implement the suggestion in #31636 will
wait for 1.14. It's too complicated for 1.13 at this point (it has
tricky interactions with plugins).
Fixes #31636
Change-Id: I35b48e8cc21cf9f93c0973edd9193d2eac197628
Reviewed-on: https://go-review.googlesource.com/c/go/+/178297
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
var fns []*obj.LSym // functions to call for package initialization
// Find imported packages with init tasks.
- for _, p := range types.ImportedPkgList() {
- if s, ok := p.LookupOK(".inittask"); ok {
- deps = append(deps, s.Linksym())
- }
+ for _, s := range types.InitSyms {
+ deps = append(deps, s.Linksym())
}
// Make a function that contains all the initialization statements.
return s
}
+// List of .inittask entries in imported packages, in source code order.
var InitSyms []*Sym
// LookupOK looks up name in pkg and reports whether it previously existed.
Name: name,
Pkg: pkg,
}
- if name == "init" {
+ if name == ".inittask" {
InitSyms = append(InitSyms, s)
}
pkg.Syms[name] = s
throw("recursive call during initialization - linker skew")
default: // not initialized yet
t.state = 1 // initialization in progress
- if raceenabled {
- // Randomize initialization order of packages t depends on.
- // TODO: enable always instead of just for race?
- s := *(*[]uintptr)(unsafe.Pointer(&slice{array: add(unsafe.Pointer(t), 3*sys.PtrSize), len: int(t.ndeps), cap: int(t.ndeps)}))
- for i := len(s) - 1; i > 0; i-- {
- j := int(fastrandn(uint32(i + 1)))
- s[i], s[j] = s[j], s[i]
- }
- }
for i := uintptr(0); i < t.ndeps; i++ {
p := add(unsafe.Pointer(t), (3+i)*sys.PtrSize)
t2 := *(**initTask)(p)
--- /dev/null
+// Copyright 2019 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
+
+func init() {
+ println("a")
+}
--- /dev/null
+// Copyright 2019 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
+
+func init() {
+ println("b")
+}
--- /dev/null
+// Copyright 2019 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 c
+
+func init() {
+ println("c")
+}
--- /dev/null
+// Copyright 2019 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 main
+
+// We want the initializers of these packages to occur in source code
+// order. See issue 31636. This is the behavior up to and including
+// 1.13. For 1.14, we will move to a variant of lexicographic ordering
+// which will require a change to the test output of this test.
+import (
+ _ "c"
+
+ _ "b"
+
+ _ "a"
+)
+
+func main() {
+}
--- /dev/null
+// rundir
+
+// Copyright 2019 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