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 10package main 11 12import "runtime" 13 14type T struct { 15 a, b, c, d, e string 16} 17 18//go:noinline 19func g() T { 20 return T{"a", "b", "c", "d", "e"} 21} 22 23//go:noinline 24func 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 33var X, Y T 34 35const N = 1000 36 37func 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