summaryrefslogtreecommitdiffstats
path: root/src/cmd/compile/internal/gc/fixedbugs_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/gc/fixedbugs_test.go')
-rw-r--r--src/cmd/compile/internal/gc/fixedbugs_test.go92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/gc/fixedbugs_test.go b/src/cmd/compile/internal/gc/fixedbugs_test.go
new file mode 100644
index 0000000..8ac4436
--- /dev/null
+++ b/src/cmd/compile/internal/gc/fixedbugs_test.go
@@ -0,0 +1,92 @@
+// Copyright 2016 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 gc
+
+import (
+ "internal/testenv"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+type T struct {
+ x [2]int64 // field that will be clobbered. Also makes type not SSAable.
+ p *byte // has a pointer
+}
+
+//go:noinline
+func makeT() T {
+ return T{}
+}
+
+var g T
+
+var sink interface{}
+
+func TestIssue15854(t *testing.T) {
+ for i := 0; i < 10000; i++ {
+ if g.x[0] != 0 {
+ t.Fatalf("g.x[0] clobbered with %x\n", g.x[0])
+ }
+ // The bug was in the following assignment. The return
+ // value of makeT() is not copied out of the args area of
+ // stack frame in a timely fashion. So when write barriers
+ // are enabled, the marshaling of the args for the write
+ // barrier call clobbers the result of makeT() before it is
+ // read by the write barrier code.
+ g = makeT()
+ sink = make([]byte, 1000) // force write barriers to eventually happen
+ }
+}
+func TestIssue15854b(t *testing.T) {
+ const N = 10000
+ a := make([]T, N)
+ for i := 0; i < N; i++ {
+ a = append(a, makeT())
+ sink = make([]byte, 1000) // force write barriers to eventually happen
+ }
+ for i, v := range a {
+ if v.x[0] != 0 {
+ t.Fatalf("a[%d].x[0] clobbered with %x\n", i, v.x[0])
+ }
+ }
+}
+
+// Test that the generated assembly has line numbers (Issue #16214).
+func TestIssue16214(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ dir, err := ioutil.TempDir("", "TestLineNumber")
+ if err != nil {
+ t.Fatalf("could not create directory: %v", err)
+ }
+ defer os.RemoveAll(dir)
+
+ src := filepath.Join(dir, "x.go")
+ err = ioutil.WriteFile(src, []byte(issue16214src), 0644)
+ if err != nil {
+ t.Fatalf("could not write file: %v", err)
+ }
+
+ cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-S", "-o", filepath.Join(dir, "out.o"), src)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("fail to run go tool compile: %v", err)
+ }
+
+ if strings.Contains(string(out), "unknown line number") {
+ t.Errorf("line number missing in assembly:\n%s", out)
+ }
+}
+
+var issue16214src = `
+package main
+
+func Mod32(x uint32) uint32 {
+ return x % 3 // frontend rewrites it as HMUL with 2863311531, the LITERAL node has unknown Pos
+}
+`