github.com/cockroachdb/tools@v0.0.0-20230222021103-a6d27438930d/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\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  }