Source file src/cmd/compile/internal/test/fixedbugs_test.go

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package test
     6  
     7  import (
     8  	"internal/testenv"
     9  	"io/ioutil"
    10  	"os"
    11  	"os/exec"
    12  	"path/filepath"
    13  	"strings"
    14  	"testing"
    15  )
    16  
    17  type T struct {
    18  	x [2]int64 // field that will be clobbered. Also makes type not SSAable.
    19  	p *byte    // has a pointer
    20  }
    21  
    22  //go:noinline
    23  func makeT() T {
    24  	return T{}
    25  }
    26  
    27  var g T
    28  
    29  var sink interface{}
    30  
    31  func TestIssue15854(t *testing.T) {
    32  	for i := 0; i < 10000; i++ {
    33  		if g.x[0] != 0 {
    34  			t.Fatalf("g.x[0] clobbered with %x\n", g.x[0])
    35  		}
    36  		// The bug was in the following assignment. The return
    37  		// value of makeT() is not copied out of the args area of
    38  		// stack frame in a timely fashion. So when write barriers
    39  		// are enabled, the marshaling of the args for the write
    40  		// barrier call clobbers the result of makeT() before it is
    41  		// read by the write barrier code.
    42  		g = makeT()
    43  		sink = make([]byte, 1000) // force write barriers to eventually happen
    44  	}
    45  }
    46  func TestIssue15854b(t *testing.T) {
    47  	const N = 10000
    48  	a := make([]T, N)
    49  	for i := 0; i < N; i++ {
    50  		a = append(a, makeT())
    51  		sink = make([]byte, 1000) // force write barriers to eventually happen
    52  	}
    53  	for i, v := range a {
    54  		if v.x[0] != 0 {
    55  			t.Fatalf("a[%d].x[0] clobbered with %x\n", i, v.x[0])
    56  		}
    57  	}
    58  }
    59  
    60  // Test that the generated assembly has line numbers (Issue #16214).
    61  func TestIssue16214(t *testing.T) {
    62  	testenv.MustHaveGoBuild(t)
    63  	dir, err := ioutil.TempDir("", "TestLineNumber")
    64  	if err != nil {
    65  		t.Fatalf("could not create directory: %v", err)
    66  	}
    67  	defer os.RemoveAll(dir)
    68  
    69  	src := filepath.Join(dir, "x.go")
    70  	err = ioutil.WriteFile(src, []byte(issue16214src), 0644)
    71  	if err != nil {
    72  		t.Fatalf("could not write file: %v", err)
    73  	}
    74  
    75  	cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-S", "-o", filepath.Join(dir, "out.o"), src)
    76  	out, err := cmd.CombinedOutput()
    77  	if err != nil {
    78  		t.Fatalf("go tool compile: %v\n%s", err, out)
    79  	}
    80  
    81  	if strings.Contains(string(out), "unknown line number") {
    82  		t.Errorf("line number missing in assembly:\n%s", out)
    83  	}
    84  }
    85  
    86  var issue16214src = `
    87  package main
    88  
    89  func Mod32(x uint32) uint32 {
    90  	return x % 3 // frontend rewrites it as HMUL with 2863311531, the LITERAL node has unknown Pos
    91  }
    92  `
    93  

View as plain text