Source file test/fixedbugs/issue16515.go
1 // run 2 3 // Copyright 2016 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 16515: spilled Duff-adjusted address may be invalid 8 9 package main 10 11 import "runtime" 12 13 type T [62]int // DUFFZERO with non-zero adjustment on AMD64 14 15 var sink interface{} 16 17 //go:noinline 18 func zero(x *T) { 19 // Two DUFFZEROs on the same address with a function call in between. 20 // Duff-adjusted address will be spilled and loaded 21 22 *x = T{} // DUFFZERO 23 runtime.GC() 24 (*x)[0] = 1 25 g() // call a function with large frame, trigger a stack move 26 *x = T{} // DUFFZERO again 27 } 28 29 //go:noinline 30 // a function with large frame 31 func g() { 32 var x [1000]int 33 _ = x 34 } 35 36 func main() { 37 var s struct { a T; b [8192-62]int } // allocate 64K, hopefully it's in a new span and a few bytes before it is garbage 38 sink = &s // force heap allocation 39 s.a[0] = 2 40 zero(&s.a) 41 if s.a[0] != 0 { 42 println("s.a[0] =", s.a[0]) 43 panic("zeroing failed") 44 } 45 46 var a T // on stack 47 a[0] = 2 48 zero(&a) 49 if a[0] != 0 { 50 println("a[0] =", a[0]) 51 panic("zeroing failed") 52 } 53 } 54