github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/pointer/testdata/channels.go (about)

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