golang.org/x/tools@v0.21.1-0.20240520172518-788d39e776b1/go/analysis/passes/copylock/testdata/src/a/copylock.go (about) 1 package a 2 3 import ( 4 "sync" 5 "sync/atomic" 6 "unsafe" 7 . "unsafe" 8 unsafe1 "unsafe" 9 ) 10 11 func OkFunc() { 12 var x *sync.Mutex 13 p := x 14 var y sync.Mutex 15 p = &y 16 17 var z = sync.Mutex{} 18 w := sync.Mutex{} 19 20 w = sync.Mutex{} 21 q := struct{ L sync.Mutex }{ 22 L: sync.Mutex{}, 23 } 24 25 yy := []Tlock{ 26 Tlock{}, 27 Tlock{ 28 once: sync.Once{}, 29 }, 30 } 31 32 nl := new(sync.Mutex) 33 mx := make([]sync.Mutex, 10) 34 xx := struct{ L *sync.Mutex }{ 35 L: new(sync.Mutex), 36 } 37 38 var pz = (sync.Mutex{}) 39 pw := (sync.Mutex{}) 40 } 41 42 type Tlock struct { 43 once sync.Once 44 } 45 46 func BadFunc() { 47 var x *sync.Mutex 48 p := x 49 var y sync.Mutex 50 p = &y 51 *p = *x // want `assignment copies lock value to \*p: sync.Mutex` 52 53 var t Tlock 54 var tp *Tlock 55 tp = &t 56 *tp = t // want `assignment copies lock value to \*tp: a.Tlock contains sync.Once contains sync\b.*` 57 t = *tp // want `assignment copies lock value to t: a.Tlock contains sync.Once contains sync\b.*` 58 59 y := *x // want "assignment copies lock value to y: sync.Mutex" 60 var z = t // want `variable declaration copies lock value to z: a.Tlock contains sync.Once contains sync\b.*` 61 62 w := struct{ L sync.Mutex }{ 63 L: *x, // want `literal copies lock value from \*x: sync.Mutex` 64 } 65 var q = map[int]Tlock{ 66 1: t, // want `literal copies lock value from t: a.Tlock contains sync.Once contains sync\b.*` 67 2: *tp, // want `literal copies lock value from \*tp: a.Tlock contains sync.Once contains sync\b.*` 68 } 69 yy := []Tlock{ 70 t, // want `literal copies lock value from t: a.Tlock contains sync.Once contains sync\b.*` 71 *tp, // want `literal copies lock value from \*tp: a.Tlock contains sync.Once contains sync\b.*` 72 } 73 74 // override 'new' keyword 75 new := func(interface{}) {} 76 new(t) // want `call of new copies lock value: a.Tlock contains sync.Once contains sync\b.*` 77 78 // copy of array of locks 79 var muA [5]sync.Mutex 80 muB := muA // want "assignment copies lock value to muB: sync.Mutex" 81 muA = muB // want "assignment copies lock value to muA: sync.Mutex" 82 muSlice := muA[:] // OK 83 84 // multidimensional array 85 var mmuA [5][5]sync.Mutex 86 mmuB := mmuA // want "assignment copies lock value to mmuB: sync.Mutex" 87 mmuA = mmuB // want "assignment copies lock value to mmuA: sync.Mutex" 88 mmuSlice := mmuA[:] // OK 89 90 // slice copy is ok 91 var fmuA [5][][5]sync.Mutex 92 fmuB := fmuA // OK 93 fmuA = fmuB // OK 94 fmuSlice := fmuA[:] // OK 95 96 // map access by single and tuple copies prohibited 97 type mut struct{ mu sync.Mutex } 98 muM := map[string]mut{ 99 "a": mut{}, 100 } 101 mumA := muM["a"] // want "assignment copies lock value to mumA: a.mut contains sync.Mutex" 102 mumB, _ := muM["a"] // want "assignment copies lock value to mumB: \\(a.mut, bool\\) contains a.mut contains sync.Mutex" 103 } 104 105 func LenAndCapOnLockArrays() { 106 var a [5]sync.Mutex 107 aLen := len(a) // OK 108 aCap := cap(a) // OK 109 110 // override 'len' and 'cap' keywords 111 112 len := func(interface{}) {} 113 len(a) // want "call of len copies lock value: sync.Mutex" 114 115 cap := func(interface{}) {} 116 cap(a) // want "call of cap copies lock value: sync.Mutex" 117 } 118 119 func SizeofMutex() { 120 var mu sync.Mutex 121 unsafe.Sizeof(mu) // OK 122 unsafe1.Sizeof(mu) // OK 123 Sizeof(mu) // OK 124 unsafe := struct{ Sizeof func(interface{}) }{} 125 unsafe.Sizeof(mu) // want "call of unsafe.Sizeof copies lock value: sync.Mutex" 126 Sizeof := func(interface{}) {} 127 Sizeof(mu) // want "call of Sizeof copies lock value: sync.Mutex" 128 } 129 130 func OffsetofMutex() { 131 type T struct { 132 f int 133 mu sync.Mutex 134 } 135 unsafe.Offsetof(T{}.mu) // OK 136 unsafe := struct{ Offsetof func(interface{}) }{} 137 unsafe.Offsetof(T{}.mu) // want "call of unsafe.Offsetof copies lock value: sync.Mutex" 138 } 139 140 func AlignofMutex() { 141 type T struct { 142 f int 143 mu sync.Mutex 144 } 145 unsafe.Alignof(T{}.mu) // OK 146 unsafe := struct{ Alignof func(interface{}) }{} 147 unsafe.Alignof(T{}.mu) // want "call of unsafe.Alignof copies lock value: sync.Mutex" 148 } 149 150 // SyncTypesCheck checks copying of sync.* types except sync.Mutex 151 func SyncTypesCheck() { 152 // sync.RWMutex copying 153 var rwmuX sync.RWMutex 154 var rwmuXX = sync.RWMutex{} 155 rwmuX1 := new(sync.RWMutex) 156 rwmuY := rwmuX // want "assignment copies lock value to rwmuY: sync.RWMutex" 157 rwmuY = rwmuX // want "assignment copies lock value to rwmuY: sync.RWMutex" 158 var rwmuYY = rwmuX // want "variable declaration copies lock value to rwmuYY: sync.RWMutex" 159 rwmuP := &rwmuX 160 rwmuZ := &sync.RWMutex{} 161 162 // sync.Cond copying 163 var condX sync.Cond 164 var condXX = sync.Cond{} 165 condX1 := new(sync.Cond) 166 condY := condX // want "assignment copies lock value to condY: sync.Cond contains sync.noCopy" 167 condY = condX // want "assignment copies lock value to condY: sync.Cond contains sync.noCopy" 168 var condYY = condX // want "variable declaration copies lock value to condYY: sync.Cond contains sync.noCopy" 169 condP := &condX 170 condZ := &sync.Cond{ 171 L: &sync.Mutex{}, 172 } 173 condZ = sync.NewCond(&sync.Mutex{}) 174 175 // sync.WaitGroup copying 176 var wgX sync.WaitGroup 177 var wgXX = sync.WaitGroup{} 178 wgX1 := new(sync.WaitGroup) 179 wgY := wgX // want "assignment copies lock value to wgY: sync.WaitGroup contains sync.noCopy" 180 wgY = wgX // want "assignment copies lock value to wgY: sync.WaitGroup contains sync.noCopy" 181 var wgYY = wgX // want "variable declaration copies lock value to wgYY: sync.WaitGroup contains sync.noCopy" 182 wgP := &wgX 183 wgZ := &sync.WaitGroup{} 184 185 // sync.Pool copying 186 var poolX sync.Pool 187 var poolXX = sync.Pool{} 188 poolX1 := new(sync.Pool) 189 poolY := poolX // want "assignment copies lock value to poolY: sync.Pool contains sync.noCopy" 190 poolY = poolX // want "assignment copies lock value to poolY: sync.Pool contains sync.noCopy" 191 var poolYY = poolX // want "variable declaration copies lock value to poolYY: sync.Pool contains sync.noCopy" 192 poolP := &poolX 193 poolZ := &sync.Pool{} 194 195 // sync.Once copying 196 var onceX sync.Once 197 var onceXX = sync.Once{} 198 onceX1 := new(sync.Once) 199 onceY := onceX // want `assignment copies lock value to onceY: sync.Once contains sync\b.*` 200 onceY = onceX // want `assignment copies lock value to onceY: sync.Once contains sync\b.*` 201 var onceYY = onceX // want `variable declaration copies lock value to onceYY: sync.Once contains sync\b.*` 202 onceP := &onceX 203 onceZ := &sync.Once{} 204 } 205 206 // AtomicTypesCheck checks copying of sync/atomic types 207 func AtomicTypesCheck() { 208 // atomic.Value copying 209 var vX atomic.Value 210 var vXX = atomic.Value{} 211 vX1 := new(atomic.Value) 212 // These are OK because the value has not been used yet. 213 // (And vet can't tell whether it has been used, so they're always OK.) 214 vY := vX 215 vY = vX 216 var vYY = vX 217 vP := &vX 218 vZ := &atomic.Value{} 219 } 220 221 // PointerRhsCheck checks that exceptions are made for pointer return values of 222 // function calls. These may be zero initialized so they are considered OK. 223 func PointerRhsCheck() { 224 newMutex := func() *sync.Mutex { return new(sync.Mutex) } 225 d := *newMutex() 226 pd := *(newMutex()) 227 }