1// +build ignore
2
3package main
4
5import "unsafe"
6
7var a int
8
9func conv1() {
10	// Conversions of channel direction.
11	ch := make(chan int)    // @line c1make
12	print((<-chan int)(ch)) // @pointsto makechan@c1make:12
13	print((chan<- int)(ch)) // @pointsto makechan@c1make:12
14}
15
16func conv2() {
17	// string -> []byte/[]rune conversion
18	s := "foo"
19	ba := []byte(s) // @line c2ba
20	ra := []rune(s) // @line c2ra
21	print(ba)       // @pointsto convert@c2ba:14
22	print(ra)       // @pointsto convert@c2ra:14
23}
24
25func conv3() {
26	// Conversion of same underlying types.
27	type PI *int
28	pi := PI(&a)
29	print(pi) // @pointsto main.a
30
31	pint := (*int)(pi)
32	print(pint) // @pointsto main.a
33
34	// Conversions between pointers to identical base types.
35	var y *PI = &pi
36	var x **int = (**int)(y)
37	print(*x) // @pointsto main.a
38	print(*y) // @pointsto main.a
39	y = (*PI)(x)
40	print(*y) // @pointsto main.a
41}
42
43func conv4() {
44	// Handling of unsafe.Pointer conversion is unsound:
45	// we lose the alias to main.a and get something like new(int) instead.
46	p := (*int)(unsafe.Pointer(&a)) // @line c2p
47	print(p)                        // @pointsto convert@c2p:13
48}
49
50// Regression test for b/8231.
51func conv5() {
52	type P unsafe.Pointer
53	var i *struct{}
54	_ = P(i)
55}
56
57func main() {
58	conv1()
59	conv2()
60	conv3()
61	conv4()
62	conv5()
63}
64