Skip to content

Commit

Permalink
cmd/compile: fix missing source information in ssa view
Browse files Browse the repository at this point in the history
Endlineno is lost when we call "genericSubst" to create the new
instantiation of the generic function. This will cause "readFuncLines"
to fail to read the target function.

To fix this issue, as @mdempsky pointed out, add the line in
cmd/compile/internal/noder/stencil.go:
    newf.Endlineno = gf.Endlineno

Fixes #51988

Change-Id: Ib408e4ed0ceb68df8dedda4fb551309e8385aada
Reviewed-on: https://go-review.googlesource.com/c/go/+/399057
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
  • Loading branch information
hopehook authored and gopherbot committed Apr 18, 2022
1 parent 91b9915 commit 3df9df8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/cmd/compile/internal/noder/stencil.go
Expand Up @@ -741,6 +741,7 @@ func (g *genInst) genericSubst(newsym *types.Sym, nameNode *ir.Name, tparams []*
// Pos of the instantiated function is same as the generic function
newf := ir.NewFunc(gf.Pos())
newf.Pragma = gf.Pragma // copy over pragmas from generic function to stenciled implementation.
newf.Endlineno = gf.Endlineno
newf.Nname = ir.NewNameAt(gf.Pos(), newsym)
newf.Nname.Func = newf
newf.Nname.Defn = newf
Expand Down
30 changes: 30 additions & 0 deletions src/runtime/callers_test.go
Expand Up @@ -309,3 +309,33 @@ func TestCallersDeferNilFuncPanicWithLoop(t *testing.T) {
// function exit, rather than at the defer statement.
state = 2
}

// issue #51988
// Func.Endlineno was lost when instantiating generic functions, leading to incorrect
// stack trace positions.
func TestCallersEndlineno(t *testing.T) {
testNormalEndlineno(t)
testGenericEndlineno[int](t)
}

func testNormalEndlineno(t *testing.T) {
defer testCallerLine(t, callerLine(t, 0)+1)
}

func testGenericEndlineno[_ any](t *testing.T) {
defer testCallerLine(t, callerLine(t, 0)+1)
}

func testCallerLine(t *testing.T, want int) {
if have := callerLine(t, 1); have != want {
t.Errorf("callerLine(1) returned %d, but want %d\n", have, want)
}
}

func callerLine(t *testing.T, skip int) int {
_, _, line, ok := runtime.Caller(skip + 1)
if !ok {
t.Fatalf("runtime.Caller(%d) failed", skip+1)
}
return line
}

0 comments on commit 3df9df8

Please sign in to comment.