modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/writebarrier.go (about) 1 // errorcheck -0 -l -d=wb 2 3 // Copyright 2015 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 // Test where write barriers are and are not emitted. 8 9 package p 10 11 import "unsafe" 12 13 func f(x **byte, y *byte) { 14 *x = y // no barrier (dead store) 15 16 z := y // no barrier 17 *x = z // ERROR "write barrier" 18 } 19 20 func f1(x *[]byte, y []byte) { 21 *x = y // no barrier (dead store) 22 23 z := y // no barrier 24 *x = z // ERROR "write barrier" 25 } 26 27 func f1a(x *[]byte, y *[]byte) { 28 *x = *y // ERROR "write barrier" 29 30 z := *y // no barrier 31 *x = z // ERROR "write barrier" 32 } 33 34 func f2(x *interface{}, y interface{}) { 35 *x = y // no barrier (dead store) 36 37 z := y // no barrier 38 *x = z // ERROR "write barrier" 39 } 40 41 func f2a(x *interface{}, y *interface{}) { 42 *x = *y // no barrier (dead store) 43 44 z := y // no barrier 45 *x = z // ERROR "write barrier" 46 } 47 48 func f3(x *string, y string) { 49 *x = y // no barrier (dead store) 50 51 z := y // no barrier 52 *x = z // ERROR "write barrier" 53 } 54 55 func f3a(x *string, y *string) { 56 *x = *y // ERROR "write barrier" 57 58 z := *y // no barrier 59 *x = z // ERROR "write barrier" 60 } 61 62 func f4(x *[2]string, y [2]string) { 63 *x = y // ERROR "write barrier" 64 65 z := y // no barrier 66 *x = z // ERROR "write barrier" 67 } 68 69 func f4a(x *[2]string, y *[2]string) { 70 *x = *y // ERROR "write barrier" 71 72 z := *y // no barrier 73 *x = z // ERROR "write barrier" 74 } 75 76 type T struct { 77 X *int 78 Y int 79 M map[int]int 80 } 81 82 func f5(t, u *T) { 83 t.X = &u.Y // ERROR "write barrier" 84 } 85 86 func f6(t *T) { 87 t.M = map[int]int{1: 2} // ERROR "write barrier" 88 } 89 90 func f7(x, y *int) []*int { 91 var z [3]*int 92 i := 0 93 z[i] = x // ERROR "write barrier" 94 i++ 95 z[i] = y // ERROR "write barrier" 96 i++ 97 return z[:i] 98 } 99 100 func f9(x *interface{}, v *byte) { 101 *x = v // ERROR "write barrier" 102 } 103 104 func f10(x *byte, f func(interface{})) { 105 f(x) 106 } 107 108 func f11(x *unsafe.Pointer, y unsafe.Pointer) { 109 *x = unsafe.Pointer(uintptr(y) + 1) // ERROR "write barrier" 110 } 111 112 func f12(x []*int, y *int) []*int { 113 // write barrier for storing y in x's underlying array 114 x = append(x, y) // ERROR "write barrier" 115 return x 116 } 117 118 func f12a(x []int, y int) []int { 119 // y not a pointer, so no write barriers in this function 120 x = append(x, y) 121 return x 122 } 123 124 func f13(x []int, y *[]int) { 125 *y = append(x, 1) // ERROR "write barrier" 126 } 127 128 func f14(y *[]int) { 129 *y = append(*y, 1) // ERROR "write barrier" 130 } 131 132 type T1 struct { 133 X *int 134 } 135 136 func f15(x []T1, y T1) []T1 { 137 return append(x, y) // ERROR "write barrier" 138 } 139 140 type T8 struct { 141 X [8]*int 142 } 143 144 func f16(x []T8, y T8) []T8 { 145 return append(x, y) // ERROR "write barrier" 146 } 147 148 func t1(i interface{}) **int { 149 // From issue 14306, make sure we have write barriers in a type switch 150 // where the assigned variable escapes. 151 switch x := i.(type) { // ERROR "write barrier" 152 case *int: 153 return &x 154 } 155 switch y := i.(type) { // no write barrier here 156 case **int: 157 return y 158 } 159 return nil 160 } 161 162 type T17 struct { 163 f func(*T17) 164 } 165 166 func f17(x *T17) { 167 // Originally from golang.org/issue/13901, but the hybrid 168 // barrier requires both to have barriers. 169 x.f = f17 // ERROR "write barrier" 170 x.f = func(y *T17) { *y = *x } // ERROR "write barrier" 171 } 172 173 type T18 struct { 174 a []int 175 s string 176 } 177 178 func f18(p *T18, x *[]int) { 179 p.a = p.a[:5] // no barrier 180 *x = (*x)[0:5] // no barrier 181 p.a = p.a[3:5] // ERROR "write barrier" 182 p.a = p.a[1:2:3] // ERROR "write barrier" 183 p.s = p.s[8:9] // ERROR "write barrier" 184 *x = (*x)[3:5] // ERROR "write barrier" 185 } 186 187 func f19(x, y *int, i int) int { 188 // Constructing a temporary slice on the stack should not 189 // require any write barriers. See issue 14263. 190 a := []*int{x, y} // no barrier 191 return *a[i] 192 } 193 194 func f20(x, y *int, i int) []*int { 195 // ... but if that temporary slice escapes, then the 196 // write barriers are necessary. 197 a := []*int{x, y} // ERROR "write barrier" 198 return a 199 } 200 201 var x21 *int 202 var y21 struct { 203 x *int 204 } 205 var z21 int 206 207 // f21x: Global -> heap pointer updates must have write barriers. 208 func f21a(x *int) { 209 x21 = x // ERROR "write barrier" 210 y21.x = x // ERROR "write barrier" 211 } 212 213 func f21b(x *int) { 214 x21 = &z21 // ERROR "write barrier" 215 y21.x = &z21 // ERROR "write barrier" 216 } 217 218 func f21c(x *int) { 219 y21 = struct{ x *int }{x} // ERROR "write barrier" 220 } 221 222 func f22(x *int) (y *int) { 223 // pointer write on stack should have no write barrier. 224 // this is a case that the frontend failed to eliminate. 225 p := &y 226 *p = x // no barrier 227 return 228 } 229 230 type T23 struct { 231 p *int 232 a int 233 } 234 235 var t23 T23 236 var i23 int 237 238 // f23x: zeroing global needs write barrier for the hybrid barrier. 239 func f23a() { 240 t23 = T23{} // ERROR "write barrier" 241 } 242 243 func f23b() { 244 // also test partial assignments 245 t23 = T23{a: 1} // ERROR "write barrier" 246 } 247 248 func f23c() { 249 t23 = T23{} // no barrier (dead store) 250 // also test partial assignments 251 t23 = T23{p: &i23} // ERROR "write barrier" 252 }