| 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 | |
| 39 | type Tlock struct { |
| 40 | once sync.Once |
| 41 | } |
| 42 | |
| 43 | func BadFunc() { |
| 44 | var x *sync.Mutex |
| 45 | p := x |
| 46 | var y sync.Mutex |
| 47 | p = &y |
| 48 | *p = *x // want `assignment copies lock value to \*p: sync.Mutex` |
| 49 | |
| 50 | var t Tlock |
| 51 | var tp *Tlock |
| 52 | tp = &t |
| 53 | *tp = t // want `assignment copies lock value to \*tp: a.Tlock contains sync.Once contains sync\b.*` |
| 54 | t = *tp // want `assignment copies lock value to t: a.Tlock contains sync.Once contains sync\b.*` |
| 55 | |
| 56 | y := *x // want "assignment copies lock value to y: sync.Mutex" |
| 57 | var z = t // want `variable declaration copies lock value to z: a.Tlock contains sync.Once contains sync\b.*` |
| 58 | |
| 59 | w := struct{ L sync.Mutex }{ |
| 60 | L: *x, // want `literal copies lock value from \*x: sync.Mutex` |
| 61 | } |
| 62 | var q = map[int]Tlock{ |
| 63 | 1: t, // want `literal copies lock value from t: a.Tlock contains sync.Once contains sync\b.*` |
| 64 | 2: *tp, // want `literal copies lock value from \*tp: a.Tlock contains sync.Once contains sync\b.*` |
| 65 | } |
| 66 | yy := []Tlock{ |
| 67 | t, // want `literal copies lock value from t: a.Tlock contains sync.Once contains sync\b.*` |
| 68 | *tp, // want `literal copies lock value from \*tp: a.Tlock contains sync.Once contains sync\b.*` |
| 69 | } |
| 70 | |
| 71 | // override 'new' keyword |
| 72 | new := func(interface{}) {} |
| 73 | new(t) // want `call of new copies lock value: a.Tlock contains sync.Once contains sync\b.*` |
| 74 | |
| 75 | // copy of array of locks |
| 76 | var muA [5]sync.Mutex |
| 77 | muB := muA // want "assignment copies lock value to muB: sync.Mutex" |
| 78 | muA = muB // want "assignment copies lock value to muA: sync.Mutex" |
| 79 | muSlice := muA[:] // OK |
| 80 | |
| 81 | // multidimensional array |
| 82 | var mmuA [5][5]sync.Mutex |
| 83 | mmuB := mmuA // want "assignment copies lock value to mmuB: sync.Mutex" |
| 84 | mmuA = mmuB // want "assignment copies lock value to mmuA: sync.Mutex" |
| 85 | mmuSlice := mmuA[:] // OK |
| 86 | |
| 87 | // slice copy is ok |
| 88 | var fmuA [5][][5]sync.Mutex |
| 89 | fmuB := fmuA // OK |
| 90 | fmuA = fmuB // OK |
| 91 | fmuSlice := fmuA[:] // OK |
| 92 | |
| 93 | // map access by single and tuple copies prohibited |
| 94 | type mut struct{ mu sync.Mutex } |
| 95 | muM := map[string]mut{ |
| 96 | "a": mut{}, |
| 97 | } |
| 98 | mumA := muM["a"] // want "assignment copies lock value to mumA: a.mut contains sync.Mutex" |
| 99 | mumB, _ := muM["a"] // want "assignment copies lock value to mumB: \\(a.mut, bool\\) contains a.mut contains sync.Mutex" |
| 100 | } |
| 101 | |
| 102 | func LenAndCapOnLockArrays() { |
| 103 | var a [5]sync.Mutex |
| 104 | aLen := len(a) // OK |
| 105 | aCap := cap(a) // OK |
| 106 | |
| 107 | // override 'len' and 'cap' keywords |
| 108 | |
| 109 | len := func(interface{}) {} |
| 110 | len(a) // want "call of len copies lock value: sync.Mutex" |
| 111 | |
| 112 | cap := func(interface{}) {} |
| 113 | cap(a) // want "call of cap copies lock value: sync.Mutex" |
| 114 | } |
| 115 | |
| 116 | func SizeofMutex() { |
| 117 | var mu sync.Mutex |
| 118 | unsafe.Sizeof(mu) // OK |
| 119 | unsafe1.Sizeof(mu) // OK |
| 120 | Sizeof(mu) // OK |
| 121 | unsafe := struct{ Sizeof func(interface{}) }{} |
| 122 | unsafe.Sizeof(mu) // want "call of unsafe.Sizeof copies lock value: sync.Mutex" |
| 123 | Sizeof := func(interface{}) {} |
| 124 | Sizeof(mu) // want "call of Sizeof copies lock value: sync.Mutex" |
| 125 | } |
| 126 | |
| 127 | func OffsetofMutex() { |
| 128 | type T struct { |
| 129 | f int |
| 130 | mu sync.Mutex |
| 131 | } |
| 132 | unsafe.Offsetof(T{}.mu) // OK |
| 133 | unsafe := struct{ Offsetof func(interface{}) }{} |
| 134 | unsafe.Offsetof(T{}.mu) // want "call of unsafe.Offsetof copies lock value: sync.Mutex" |
| 135 | } |
| 136 | |
| 137 | func AlignofMutex() { |
| 138 | type T struct { |
| 139 | f int |
| 140 | mu sync.Mutex |
| 141 | } |
| 142 | unsafe.Alignof(T{}.mu) // OK |
| 143 | unsafe := struct{ Alignof func(interface{}) }{} |
| 144 | unsafe.Alignof(T{}.mu) // want "call of unsafe.Alignof copies lock value: sync.Mutex" |
| 145 | } |
| 146 | |
| 147 | // SyncTypesCheck checks copying of sync.* types except sync.Mutex |
| 148 | func SyncTypesCheck() { |
| 149 | // sync.RWMutex copying |
| 150 | var rwmuX sync.RWMutex |
| 151 | var rwmuXX = sync.RWMutex{} |
| 152 | rwmuX1 := new(sync.RWMutex) |
| 153 | rwmuY := rwmuX // want "assignment copies lock value to rwmuY: sync.RWMutex" |
| 154 | rwmuY = rwmuX // want "assignment copies lock value to rwmuY: sync.RWMutex" |
| 155 | var rwmuYY = rwmuX // want "variable declaration copies lock value to rwmuYY: sync.RWMutex" |
| 156 | rwmuP := &rwmuX |
| 157 | rwmuZ := &sync.RWMutex{} |
| 158 | |
| 159 | // sync.Cond copying |
| 160 | var condX sync.Cond |
| 161 | var condXX = sync.Cond{} |
| 162 | condX1 := new(sync.Cond) |
| 163 | condY := condX // want "assignment copies lock value to condY: sync.Cond contains sync.noCopy" |
| 164 | condY = condX // want "assignment copies lock value to condY: sync.Cond contains sync.noCopy" |
| 165 | var condYY = condX // want "variable declaration copies lock value to condYY: sync.Cond contains sync.noCopy" |
| 166 | condP := &condX |
| 167 | condZ := &sync.Cond{ |
| 168 | L: &sync.Mutex{}, |
| 169 | } |
| 170 | condZ = sync.NewCond(&sync.Mutex{}) |
| 171 | |
| 172 | // sync.WaitGroup copying |
| 173 | var wgX sync.WaitGroup |
| 174 | var wgXX = sync.WaitGroup{} |
| 175 | wgX1 := new(sync.WaitGroup) |
| 176 | wgY := wgX // want "assignment copies lock value to wgY: sync.WaitGroup contains sync.noCopy" |
| 177 | wgY = wgX // want "assignment copies lock value to wgY: sync.WaitGroup contains sync.noCopy" |
| 178 | var wgYY = wgX // want "variable declaration copies lock value to wgYY: sync.WaitGroup contains sync.noCopy" |
| 179 | wgP := &wgX |
| 180 | wgZ := &sync.WaitGroup{} |
| 181 | |
| 182 | // sync.Pool copying |
| 183 | var poolX sync.Pool |
| 184 | var poolXX = sync.Pool{} |
| 185 | poolX1 := new(sync.Pool) |
| 186 | poolY := poolX // want "assignment copies lock value to poolY: sync.Pool contains sync.noCopy" |
| 187 | poolY = poolX // want "assignment copies lock value to poolY: sync.Pool contains sync.noCopy" |
| 188 | var poolYY = poolX // want "variable declaration copies lock value to poolYY: sync.Pool contains sync.noCopy" |
| 189 | poolP := &poolX |
| 190 | poolZ := &sync.Pool{} |
| 191 | |
| 192 | // sync.Once copying |
| 193 | var onceX sync.Once |
| 194 | var onceXX = sync.Once{} |
| 195 | onceX1 := new(sync.Once) |
| 196 | onceY := onceX // want `assignment copies lock value to onceY: sync.Once contains sync\b.*` |
| 197 | onceY = onceX // want `assignment copies lock value to onceY: sync.Once contains sync\b.*` |
| 198 | var onceYY = onceX // want `variable declaration copies lock value to onceYY: sync.Once contains sync\b.*` |
| 199 | onceP := &onceX |
| 200 | onceZ := &sync.Once{} |
| 201 | } |
| 202 | |
| 203 | // AtomicTypesCheck checks copying of sync/atomic types |
| 204 | func AtomicTypesCheck() { |
| 205 | // atomic.Value copying |
| 206 | var vX atomic.Value |
| 207 | var vXX = atomic.Value{} |
| 208 | vX1 := new(atomic.Value) |
| 209 | // These are OK because the value has not been used yet. |
| 210 | // (And vet can't tell whether it has been used, so they're always OK.) |
| 211 | vY := vX |
| 212 | vY = vX |
| 213 | var vYY = vX |
| 214 | vP := &vX |
| 215 | vZ := &atomic.Value{} |
| 216 | } |
| 217 |
Members