github.com/euank/go@v0.0.0-20160829210321-495514729181/src/cmd/compile/internal/gc/fixedbugs_test.go (about)

     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 gc
     6  
     7  import "testing"
     8  
     9  type T struct {
    10  	x [2]int64 // field that will be clobbered. Also makes type not SSAable.
    11  	p *byte    // has a pointer
    12  }
    13  
    14  //go:noinline
    15  func makeT() T {
    16  	return T{}
    17  }
    18  
    19  var g T
    20  
    21  var sink []byte
    22  
    23  func TestIssue15854(t *testing.T) {
    24  	for i := 0; i < 10000; i++ {
    25  		if g.x[0] != 0 {
    26  			t.Fatalf("g.x[0] clobbered with %x\n", g.x[0])
    27  		}
    28  		// The bug was in the following assignment. The return
    29  		// value of makeT() is not copied out of the args area of
    30  		// stack frame in a timely fashion. So when write barriers
    31  		// are enabled, the marshaling of the args for the write
    32  		// barrier call clobbers the result of makeT() before it is
    33  		// read by the write barrier code.
    34  		g = makeT()
    35  		sink = make([]byte, 1000) // force write barriers to eventually happen
    36  	}
    37  }
    38  func TestIssue15854b(t *testing.T) {
    39  	const N = 10000
    40  	a := make([]T, N)
    41  	for i := 0; i < N; i++ {
    42  		a = append(a, makeT())
    43  		sink = make([]byte, 1000) // force write barriers to eventually happen
    44  	}
    45  	for i, v := range a {
    46  		if v.x[0] != 0 {
    47  			t.Fatalf("a[%d].x[0] clobbered with %x\n", i, v.x[0])
    48  		}
    49  	}
    50  }