github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/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  
    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.Mutex`
    54  	t = *tp // want "assignment copies lock value to t: a.Tlock contains sync.Once contains sync.Mutex"
    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.Mutex"
    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.Mutex"
    64  		2: *tp, // want `literal copies lock value from \*tp: a.Tlock contains sync.Once contains sync.Mutex`
    65  	}
    66  	yy := []Tlock{
    67  		t,   // want "literal copies lock value from t: a.Tlock contains sync.Once contains sync.Mutex"
    68  		*tp, // want `literal copies lock value from \*tp: a.Tlock contains sync.Once contains sync.Mutex`
    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.Mutex"
    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  // SyncTypesCheck checks copying of sync.* types except sync.Mutex
   128  func SyncTypesCheck() {
   129  	// sync.RWMutex copying
   130  	var rwmuX sync.RWMutex
   131  	var rwmuXX = sync.RWMutex{}
   132  	rwmuX1 := new(sync.RWMutex)
   133  	rwmuY := rwmuX     // want "assignment copies lock value to rwmuY: sync.RWMutex"
   134  	rwmuY = rwmuX      // want "assignment copies lock value to rwmuY: sync.RWMutex"
   135  	var rwmuYY = rwmuX // want "variable declaration copies lock value to rwmuYY: sync.RWMutex"
   136  	rwmuP := &rwmuX
   137  	rwmuZ := &sync.RWMutex{}
   138  
   139  	// sync.Cond copying
   140  	var condX sync.Cond
   141  	var condXX = sync.Cond{}
   142  	condX1 := new(sync.Cond)
   143  	condY := condX     // want "assignment copies lock value to condY: sync.Cond contains sync.noCopy"
   144  	condY = condX      // want "assignment copies lock value to condY: sync.Cond contains sync.noCopy"
   145  	var condYY = condX // want "variable declaration copies lock value to condYY: sync.Cond contains sync.noCopy"
   146  	condP := &condX
   147  	condZ := &sync.Cond{
   148  		L: &sync.Mutex{},
   149  	}
   150  	condZ = sync.NewCond(&sync.Mutex{})
   151  
   152  	// sync.WaitGroup copying
   153  	var wgX sync.WaitGroup
   154  	var wgXX = sync.WaitGroup{}
   155  	wgX1 := new(sync.WaitGroup)
   156  	wgY := wgX     // want "assignment copies lock value to wgY: sync.WaitGroup contains sync.noCopy"
   157  	wgY = wgX      // want "assignment copies lock value to wgY: sync.WaitGroup contains sync.noCopy"
   158  	var wgYY = wgX // want "variable declaration copies lock value to wgYY: sync.WaitGroup contains sync.noCopy"
   159  	wgP := &wgX
   160  	wgZ := &sync.WaitGroup{}
   161  
   162  	// sync.Pool copying
   163  	var poolX sync.Pool
   164  	var poolXX = sync.Pool{}
   165  	poolX1 := new(sync.Pool)
   166  	poolY := poolX     // want "assignment copies lock value to poolY: sync.Pool contains sync.noCopy"
   167  	poolY = poolX      // want "assignment copies lock value to poolY: sync.Pool contains sync.noCopy"
   168  	var poolYY = poolX // want "variable declaration copies lock value to poolYY: sync.Pool contains sync.noCopy"
   169  	poolP := &poolX
   170  	poolZ := &sync.Pool{}
   171  
   172  	// sync.Once copying
   173  	var onceX sync.Once
   174  	var onceXX = sync.Once{}
   175  	onceX1 := new(sync.Once)
   176  	onceY := onceX     // want "assignment copies lock value to onceY: sync.Once contains sync.Mutex"
   177  	onceY = onceX      // want "assignment copies lock value to onceY: sync.Once contains sync.Mutex"
   178  	var onceYY = onceX // want "variable declaration copies lock value to onceYY: sync.Once contains sync.Mutex"
   179  	onceP := &onceX
   180  	onceZ := &sync.Once{}
   181  }
   182  
   183  // AtomicTypesCheck checks copying of sync/atomic types
   184  func AtomicTypesCheck() {
   185  	// atomic.Value copying
   186  	var vX atomic.Value
   187  	var vXX = atomic.Value{}
   188  	vX1 := new(atomic.Value)
   189  	// These are OK because the value has not been used yet.
   190  	// (And vet can't tell whether it has been used, so they're always OK.)
   191  	vY := vX
   192  	vY = vX
   193  	var vYY = vX
   194  	vP := &vX
   195  	vZ := &atomic.Value{}
   196  }