Navigation Menu

Skip to content

Commit

Permalink
cmd/compile: add line number test for #49436
Browse files Browse the repository at this point in the history
This enhances the existing line number test
to allow a specific -gcflags (e.g., -G=3)
and to permit ignoring duplicate line numbers
(which is arguably a bug, but not THIS bug,
and it lowers the risk of a flaky test).

Limited to Linux/Darwin and amd64/arm64,
also tests with "unified" mangling.

And, using these new powers, adds a test.

Updates #49436.

Change-Id: I09c82e6a08d53edd5a752522a827e872d3e16e0b
Reviewed-on: https://go-review.googlesource.com/c/go/+/362714
Trust: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
  • Loading branch information
dr2chase committed Nov 9, 2021
1 parent 5430203 commit a096316
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 9 deletions.
49 changes: 40 additions & 9 deletions src/cmd/compile/internal/ssa/debug_lines_test.go
Expand Up @@ -8,10 +8,10 @@ import (
"bufio"
"bytes"
"flag"
"internal/buildcfg"
"runtime"
"sort"

// "flag"
"fmt"
"internal/testenv"
"io/ioutil"
Expand Down Expand Up @@ -45,24 +45,43 @@ func testGoArch() string {
return *testGoArchFlag
}

func TestDebugLines(t *testing.T) {
func TestDebugLinesSayHi(t *testing.T) {
// This test is potentially fragile, the goal is that debugging should step properly through "sayhi"
// If the blocks are reordered in a way that changes the statement order but execution flows correctly,
// then rearrange the expected numbers. Register abi and not-register-abi also have different sequences,
// at least for now.

switch testGoArch() {
case "arm64", "amd64": // register ABI
testDebugLines(t, "sayhi.go", "sayhi", []int{8, 9, 10, 11})
testDebugLines(t, "-N -l", "sayhi.go", "sayhi", []int{8, 9, 10, 11}, false)

case "arm", "386": // probably not register ABI for a while
testDebugLines(t, "sayhi.go", "sayhi", []int{9, 10, 11})
testDebugLines(t, "-N -l", "sayhi.go", "sayhi", []int{9, 10, 11}, false)

default: // expect ppc64le and riscv will pick up register ABI soonish, not sure about others
t.Skip("skipped for many architectures, also changes w/ register ABI")
}
}

func TestDebugLinesPushback(t *testing.T) {
if runtime.GOOS != "linux" && runtime.GOOS != "darwin" { // in particular, it could be windows.
t.Skip("this test depends on creating a file with a wonky name, only works for sure on Linux and Darwin")
}

switch testGoArch() {
default:
t.Skip("skipped for many architectures")

case "arm64", "amd64": // register ABI
fn := "(*List[go.shape.int_0]).PushBack"
if buildcfg.Experiment.Unified {
// Unified mangles differently
fn = "(*List[int]).PushBack"
}
testDebugLines(t, "-N -l -G=3", "pushback.go", fn, []int{17, 18, 19, 20, 21, 22, 24}, true)
}
}

func TestInlineLines(t *testing.T) {
if runtime.GOARCH != "amd64" && *testGoArchFlag == "" {
// As of september 2021, works for everything except mips64, but still potentially fragile
Expand Down Expand Up @@ -181,8 +200,8 @@ func testInlineStack(t *testing.T, file, function string, wantStacks [][]int) {
// then verifies that the statement-marked lines in that file are the same as those in wantStmts
// These files must all be short because this is super-fragile.
// "go build" is run in a temporary directory that is normally deleted, unless -test.v
func testDebugLines(t *testing.T, file, function string, wantStmts []int) {
dumpBytes := compileAndDump(t, file, function, "-N -l")
func testDebugLines(t *testing.T, gcflags, file, function string, wantStmts []int, ignoreRepeats bool) {
dumpBytes := compileAndDump(t, file, function, gcflags)
dump := bufio.NewScanner(bytes.NewReader(dumpBytes))
var gotStmts []int
dumpLineNum := 0
Expand All @@ -201,8 +220,20 @@ func testDebugLines(t *testing.T, file, function string, wantStmts []int) {
gotStmts = append(gotStmts, int(stmt))
}
}
if !reflect.DeepEqual(wantStmts, gotStmts) {
t.Errorf("wanted stmts %v but got %v", wantStmts, gotStmts)
}
if ignoreRepeats { // remove repeats from gotStmts
newGotStmts := []int{gotStmts[0]}
for _, x := range gotStmts {
if x != newGotStmts[len(newGotStmts)-1] {
newGotStmts = append(newGotStmts, x)
}
}
if !reflect.DeepEqual(wantStmts, newGotStmts) {
t.Errorf("wanted stmts %v but got %v (with repeats still in: %v)", wantStmts, newGotStmts, gotStmts)
}

} else {
if !reflect.DeepEqual(wantStmts, gotStmts) {
t.Errorf("wanted stmts %v but got %v", wantStmts, gotStmts)
}
}
}
30 changes: 30 additions & 0 deletions src/cmd/compile/internal/ssa/testdata/pushback.go
@@ -0,0 +1,30 @@
package main

type Node struct {
Circular bool
}

type ExtNode[V any] struct {
v V
Node
}

type List[V any] struct {
root *ExtNode[V]
len int
}

func (list *List[V]) PushBack(arg V) {
if list.len == 0 {
list.root = &ExtNode[V]{v: arg}
list.root.Circular = true
list.len++
return
}
list.len++
}

func main() {
var v List[int]
v.PushBack(1)
}

0 comments on commit a096316

Please sign in to comment.