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  }