// fninit hand-crafts package initialization code.
//
+// func init.ializers() { (0)
+// <init stmts>
+// }
// var initdone· uint8 (1)
// func init() { (2)
// if initdone· > 1 { (3)
// initdone· = 1 (5)
// // over all matching imported symbols
// <pkg>.init() (6)
-// { <init stmts> } (7)
+// init.ializers() (7)
// init.<n>() // if any (8)
// initdone· = 2 (9)
// return (10)
return
}
+ // (0)
+ // Make a function that contains all the initialization statements.
+ // This is a separate function because we want it to appear in
+ // stack traces, where the init function itself does not.
+ var initializers *types.Sym
+ if len(nf) > 0 {
+ lineno = nf[0].Pos // prolog/epilog gets line number of first init stmt
+ initializers = lookup("init.ializers")
+ disableExport(initializers)
+ fn := dclfunc(initializers, nod(OTFUNC, nil, nil))
+ fn.Nbody.Set(nf)
+ funcbody()
+
+ fn = typecheck(fn, ctxStmt)
+ Curfn = fn
+ typecheckslice(nf, ctxStmt)
+ Curfn = nil
+ funccompile(fn)
+ lineno = autogeneratedPos
+ }
+
var r []*Node
// (1)
}
// (7)
- r = append(r, nf...)
+ if initializers != nil {
+ n := newname(initializers)
+ addvar(n, functype(nil, nil, nil), PFUNC)
+ r = append(r, nod(OCALL, n, nil))
+ }
// (8)
case "runtime.panicwrap":
return FuncID_panicwrap
}
- if file == "<autogenerated>" && !strings.HasSuffix(name, ".init") {
+ if file == "<autogenerated>" {
return FuncID_wrapper
}
if strings.HasPrefix(name, "runtime.call") {
--- /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.
+
+// Make sure tracebacks from initialization code are reported correctly.
+
+package a
+
+import (
+ "fmt"
+ "runtime"
+ "strings"
+)
+
+var x = f() // line 15
+
+func f() int {
+ var b [4096]byte
+ n := runtime.Stack(b[:], false) // line 19
+ s := string(b[:n])
+ var pcs [10]uintptr
+ n = runtime.Callers(1, pcs[:]) // line 22
+
+ // Check the Stack results.
+ if debug {
+ println(s)
+ }
+ if strings.Contains(s, "autogenerated") {
+ panic("autogenerated code in traceback")
+ }
+ if !strings.Contains(s, "a.go:15") {
+ panic("missing a.go:15")
+ }
+ if !strings.Contains(s, "a.go:19") {
+ panic("missing a.go:19")
+ }
+ if !strings.Contains(s, "a.init.ializers") {
+ panic("missing a.init.ializers")
+ }
+
+ // Check the CallersFrames results.
+ if debug {
+ iter := runtime.CallersFrames(pcs[:n])
+ for {
+ f, more := iter.Next()
+ fmt.Printf("%s %s:%d\n", f.Function, f.File, f.Line)
+ if !more {
+ break
+ }
+ }
+ }
+ iter := runtime.CallersFrames(pcs[:n])
+ f, more := iter.Next()
+ if f.Function != "a.f" || !strings.HasSuffix(f.File, "a.go") || f.Line != 22 {
+ panic(fmt.Sprintf("bad f %v\n", f))
+ }
+ if !more {
+ panic("traceback truncated after f")
+ }
+ f, more = iter.Next()
+ if f.Function != "a.init.ializers" || !strings.HasSuffix(f.File, "a.go") || f.Line != 15 {
+ panic(fmt.Sprintf("bad init.ializers %v\n", f))
+ }
+ if !more {
+ panic("traceback truncated after init.ializers")
+ }
+ f, _ = iter.Next()
+ if f.Function != "runtime.main" {
+ panic("runtime.main missing")
+ }
+
+ return 0
+}
+
+const debug = false
--- /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
+
+import _ "./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.
+
+// Make sure tracebacks from initialization code are reported correctly.
+
+package ignored