Source file test/fixedbugs/issue30977.go

     1  // run
     2  
     3  // Copyright 2019 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // Issue 30977: write barrier call clobbers volatile
     8  // value when there are multiple uses of the value.
     9  
    10  package main
    11  
    12  import "runtime"
    13  
    14  type T struct {
    15  	a, b, c, d, e string
    16  }
    17  
    18  //go:noinline
    19  func g() T {
    20  	return T{"a", "b", "c", "d", "e"}
    21  }
    22  
    23  //go:noinline
    24  func f() {
    25  	// The compiler optimizes this to direct copying
    26  	// the call result to both globals, with write
    27  	// barriers. The first write barrier call clobbers
    28  	// the result of g on stack.
    29  	X = g()
    30  	Y = X
    31  }
    32  
    33  var X, Y T
    34  
    35  const N = 1000
    36  
    37  func main() {
    38  	// Keep GC running so the write barrier is on.
    39  	go func() {
    40  		for {
    41  			runtime.GC()
    42  		}
    43  	}()
    44  
    45  	for i := 0; i < N; i++ {
    46  		runtime.Gosched()
    47  		f()
    48  		if X != Y {
    49  			panic("FAIL")
    50  		}
    51  	}
    52  }
    53  

View as plain text