github.com/v2fly/tools@v0.100.0/go/pointer/testdata/channels.go (about)

     1  // +build ignore
     2  
     3  package main
     4  
     5  func incr(x int) int { return x + 1 }
     6  
     7  func decr(x int) int { return x - 1 }
     8  
     9  var unknown bool // defeat dead-code elimination
    10  
    11  func chan1() {
    12  	chA := make(chan func(int) int, 0) // @line c1makeA
    13  	chB := make(chan func(int) int, 0) // @line c1makeB
    14  	chA <- incr
    15  	chB <- decr
    16  	chB <- func(int) int { return 1 }
    17  
    18  	print(chA)   // @pointsto makechan@c1makeA:13
    19  	print(<-chA) // @pointsto main.incr
    20  
    21  	print(chB)   // @pointsto makechan@c1makeB:13
    22  	print(<-chB) // @pointsto main.decr | main.chan1$1
    23  }
    24  
    25  func chan2() {
    26  	chA := make(chan func(int) int, 0) // @line c2makeA
    27  	chB := make(chan func(int) int, 0) // @line c2makeB
    28  	chA <- incr
    29  	chB <- decr
    30  	chB <- func(int) int { return 1 }
    31  
    32  	// Channels flow together.
    33  	// Labelsets remain distinct but elements are merged.
    34  	chAB := chA
    35  	if unknown {
    36  		chAB = chB
    37  	}
    38  
    39  	print(chA)   // @pointsto makechan@c2makeA:13
    40  	print(<-chA) // @pointsto main.incr
    41  
    42  	print(chB)   // @pointsto makechan@c2makeB:13
    43  	print(<-chB) // @pointsto main.decr | main.chan2$1
    44  
    45  	print(chAB)   // @pointsto makechan@c2makeA:13 | makechan@c2makeB:13
    46  	print(<-chAB) // @pointsto main.incr | main.decr | main.chan2$1
    47  
    48  	(<-chA)(3)
    49  }
    50  
    51  // @calls main.chan2 -> main.incr
    52  
    53  func chan3() {
    54  	chA := make(chan func(int) int, 0) // @line c3makeA
    55  	chB := make(chan func(int) int, 0) // @line c3makeB
    56  	chA <- incr
    57  	chB <- decr
    58  	chB <- func(int) int { return 1 }
    59  	print(chA)   // @pointsto makechan@c3makeA:13
    60  	print(<-chA) // @pointsto main.incr
    61  	print(chB)   // @pointsto makechan@c3makeB:13
    62  	print(<-chB) // @pointsto main.decr | main.chan3$1
    63  
    64  	(<-chA)(3)
    65  }
    66  
    67  // @calls main.chan3 -> main.incr
    68  
    69  func chan4() {
    70  	chA := make(chan func(int) int, 0) // @line c4makeA
    71  	chB := make(chan func(int) int, 0) // @line c4makeB
    72  
    73  	select {
    74  	case chA <- incr:
    75  	case chB <- decr:
    76  	case a := <-chA:
    77  		print(a) // @pointsto main.incr
    78  	case b := <-chB:
    79  		print(b) // @pointsto main.decr
    80  	default:
    81  		print(chA) // @pointsto makechan@c4makeA:13
    82  		print(chB) // @pointsto makechan@c4makeB:13
    83  	}
    84  
    85  	for k := range chA {
    86  		print(k) // @pointsto main.incr
    87  	}
    88  	// Exercise constraint generation (regtest for a crash).
    89  	for range chA {
    90  	}
    91  }
    92  
    93  // Multi-word channel value in select with multiple receive cases.
    94  // (Regtest for a crash.)
    95  func chan5() {
    96  	type T struct {
    97  		x *int
    98  		y interface{}
    99  	}
   100  	ch := make(chan T)
   101  	ch <- T{new(int), incr} // @line ch5new
   102  	select {
   103  	case a := <-ch:
   104  		print(a.x) // @pointsto new@ch5new:13
   105  		print(a.y) // @types func(x int) int
   106  	case b := <-ch:
   107  		print(b.x) // @pointsto new@ch5new:13
   108  		print(b.y) // @types func(x int) int
   109  	}
   110  }
   111  
   112  func main() {
   113  	chan1()
   114  	chan2()
   115  	chan3()
   116  	chan4()
   117  	chan5()
   118  }