| package a |
| |
| import ( |
| "sync" |
| "sync/atomic" |
| "unsafe" |
| . "unsafe" |
| unsafe1 "unsafe" |
| ) |
| |
| func OkFunc() { |
| var x *sync.Mutex |
| p := x |
| var y sync.Mutex |
| p = &y |
| |
| var z = sync.Mutex{} |
| w := sync.Mutex{} |
| |
| w = sync.Mutex{} |
| q := struct{ L sync.Mutex }{ |
| L: sync.Mutex{}, |
| } |
| |
| yy := []Tlock{ |
| Tlock{}, |
| Tlock{ |
| once: sync.Once{}, |
| }, |
| } |
| |
| nl := new(sync.Mutex) |
| mx := make([]sync.Mutex, 10) |
| xx := struct{ L *sync.Mutex }{ |
| L: new(sync.Mutex), |
| } |
| } |
| |
| type Tlock struct { |
| once sync.Once |
| } |
| |
| func BadFunc() { |
| var x *sync.Mutex |
| p := x |
| var y sync.Mutex |
| p = &y |
| *p = *x // want `assignment copies lock value to \*p: sync.Mutex` |
| |
| var t Tlock |
| var tp *Tlock |
| tp = &t |
| *tp = t // want `assignment copies lock value to \*tp: a.Tlock contains sync.Once contains sync.Mutex` |
| t = *tp // want "assignment copies lock value to t: a.Tlock contains sync.Once contains sync.Mutex" |
| |
| y := *x // want "assignment copies lock value to y: sync.Mutex" |
| var z = t // want "variable declaration copies lock value to z: a.Tlock contains sync.Once contains sync.Mutex" |
| |
| w := struct{ L sync.Mutex }{ |
| L: *x, // want `literal copies lock value from \*x: sync.Mutex` |
| } |
| var q = map[int]Tlock{ |
| 1: t, // want "literal copies lock value from t: a.Tlock contains sync.Once contains sync.Mutex" |
| 2: *tp, // want `literal copies lock value from \*tp: a.Tlock contains sync.Once contains sync.Mutex` |
| } |
| yy := []Tlock{ |
| t, // want "literal copies lock value from t: a.Tlock contains sync.Once contains sync.Mutex" |
| *tp, // want `literal copies lock value from \*tp: a.Tlock contains sync.Once contains sync.Mutex` |
| } |
| |
| // override 'new' keyword |
| new := func(interface{}) {} |
| new(t) // want "call of new copies lock value: a.Tlock contains sync.Once contains sync.Mutex" |
| |
| // copy of array of locks |
| var muA [5]sync.Mutex |
| muB := muA // want "assignment copies lock value to muB: sync.Mutex" |
| muA = muB // want "assignment copies lock value to muA: sync.Mutex" |
| muSlice := muA[:] // OK |
| |
| // multidimensional array |
| var mmuA [5][5]sync.Mutex |
| mmuB := mmuA // want "assignment copies lock value to mmuB: sync.Mutex" |
| mmuA = mmuB // want "assignment copies lock value to mmuA: sync.Mutex" |
| mmuSlice := mmuA[:] // OK |
| |
| // slice copy is ok |
| var fmuA [5][][5]sync.Mutex |
| fmuB := fmuA // OK |
| fmuA = fmuB // OK |
| fmuSlice := fmuA[:] // OK |
| } |
| |
| func LenAndCapOnLockArrays() { |
| var a [5]sync.Mutex |
| aLen := len(a) // OK |
| aCap := cap(a) // OK |
| |
| // override 'len' and 'cap' keywords |
| |
| len := func(interface{}) {} |
| len(a) // want "call of len copies lock value: sync.Mutex" |
| |
| cap := func(interface{}) {} |
| cap(a) // want "call of cap copies lock value: sync.Mutex" |
| } |
| |
| func SizeofMutex() { |
| var mu sync.Mutex |
| unsafe.Sizeof(mu) // OK |
| unsafe1.Sizeof(mu) // OK |
| Sizeof(mu) // OK |
| unsafe := struct{ Sizeof func(interface{}) }{} |
| unsafe.Sizeof(mu) // want "call of unsafe.Sizeof copies lock value: sync.Mutex" |
| Sizeof := func(interface{}) {} |
| Sizeof(mu) // want "call of Sizeof copies lock value: sync.Mutex" |
| } |
| |
| // SyncTypesCheck checks copying of sync.* types except sync.Mutex |
| func SyncTypesCheck() { |
| // sync.RWMutex copying |
| var rwmuX sync.RWMutex |
| var rwmuXX = sync.RWMutex{} |
| rwmuX1 := new(sync.RWMutex) |
| rwmuY := rwmuX // want "assignment copies lock value to rwmuY: sync.RWMutex" |
| rwmuY = rwmuX // want "assignment copies lock value to rwmuY: sync.RWMutex" |
| var rwmuYY = rwmuX // want "variable declaration copies lock value to rwmuYY: sync.RWMutex" |
| rwmuP := &rwmuX |
| rwmuZ := &sync.RWMutex{} |
| |
| // sync.Cond copying |
| var condX sync.Cond |
| var condXX = sync.Cond{} |
| condX1 := new(sync.Cond) |
| condY := condX // want "assignment copies lock value to condY: sync.Cond contains sync.noCopy" |
| condY = condX // want "assignment copies lock value to condY: sync.Cond contains sync.noCopy" |
| var condYY = condX // want "variable declaration copies lock value to condYY: sync.Cond contains sync.noCopy" |
| condP := &condX |
| condZ := &sync.Cond{ |
| L: &sync.Mutex{}, |
| } |
| condZ = sync.NewCond(&sync.Mutex{}) |
| |
| // sync.WaitGroup copying |
| var wgX sync.WaitGroup |
| var wgXX = sync.WaitGroup{} |
| wgX1 := new(sync.WaitGroup) |
| wgY := wgX // want "assignment copies lock value to wgY: sync.WaitGroup contains sync.noCopy" |
| wgY = wgX // want "assignment copies lock value to wgY: sync.WaitGroup contains sync.noCopy" |
| var wgYY = wgX // want "variable declaration copies lock value to wgYY: sync.WaitGroup contains sync.noCopy" |
| wgP := &wgX |
| wgZ := &sync.WaitGroup{} |
| |
| // sync.Pool copying |
| var poolX sync.Pool |
| var poolXX = sync.Pool{} |
| poolX1 := new(sync.Pool) |
| poolY := poolX // want "assignment copies lock value to poolY: sync.Pool contains sync.noCopy" |
| poolY = poolX // want "assignment copies lock value to poolY: sync.Pool contains sync.noCopy" |
| var poolYY = poolX // want "variable declaration copies lock value to poolYY: sync.Pool contains sync.noCopy" |
| poolP := &poolX |
| poolZ := &sync.Pool{} |
| |
| // sync.Once copying |
| var onceX sync.Once |
| var onceXX = sync.Once{} |
| onceX1 := new(sync.Once) |
| onceY := onceX // want "assignment copies lock value to onceY: sync.Once contains sync.Mutex" |
| onceY = onceX // want "assignment copies lock value to onceY: sync.Once contains sync.Mutex" |
| var onceYY = onceX // want "variable declaration copies lock value to onceYY: sync.Once contains sync.Mutex" |
| onceP := &onceX |
| onceZ := &sync.Once{} |
| } |
| |
| // AtomicTypesCheck checks copying of sync/atomic types |
| func AtomicTypesCheck() { |
| // atomic.Value copying |
| var vX atomic.Value |
| var vXX = atomic.Value{} |
| vX1 := new(atomic.Value) |
| // These are OK because the value has not been used yet. |
| // (And vet can't tell whether it has been used, so they're always OK.) |
| vY := vX |
| vY = vX |
| var vYY = vX |
| vP := &vX |
| vZ := &atomic.Value{} |
| } |