1// run
2
3// Copyright 2011 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Test reordering of assignments.
8
9package main
10
11import "fmt"
12
13func main() {
14	p1()
15	p2()
16	p3()
17	p4()
18	p5()
19	p6()
20	p7()
21	p8()
22	p9()
23	p10()
24	p11()
25}
26
27var gx []int
28
29func f(i int) int {
30	return gx[i]
31}
32
33func check(x []int, x0, x1, x2 int) {
34	if x[0] != x0 || x[1] != x1 || x[2] != x2 {
35		fmt.Printf("%v, want %d,%d,%d\n", x, x0, x1, x2)
36		panic("failed")
37	}
38}
39
40func check3(x, y, z, xx, yy, zz int) {
41	if x != xx || y != yy || z != zz {
42		fmt.Printf("%d,%d,%d, want %d,%d,%d\n", x, y, z, xx, yy, zz)
43		panic("failed")
44	}
45}
46
47func p1() {
48	x := []int{1, 2, 3}
49	i := 0
50	i, x[i] = 1, 100
51	_ = i
52	check(x, 100, 2, 3)
53}
54
55func p2() {
56	x := []int{1, 2, 3}
57	i := 0
58	x[i], i = 100, 1
59	_ = i
60	check(x, 100, 2, 3)
61}
62
63func p3() {
64	x := []int{1, 2, 3}
65	y := x
66	gx = x
67	x[1], y[0] = f(0), f(1)
68	check(x, 2, 1, 3)
69}
70
71func p4() {
72	x := []int{1, 2, 3}
73	y := x
74	gx = x
75	x[1], y[0] = gx[0], gx[1]
76	check(x, 2, 1, 3)
77}
78
79func p5() {
80	x := []int{1, 2, 3}
81	y := x
82	p := &x[0]
83	q := &x[1]
84	*p, *q = x[1], y[0]
85	check(x, 2, 1, 3)
86}
87
88func p6() {
89	x := 1
90	y := 2
91	z := 3
92	px := &x
93	py := &y
94	*px, *py = y, x
95	check3(x, y, z, 2, 1, 3)
96}
97
98func f1(x, y, z int) (xx, yy, zz int) {
99	return x, y, z
100}
101
102func f2() (x, y, z int) {
103	return f1(2, 1, 3)
104}
105
106func p7() {
107	x, y, z := f2()
108	check3(x, y, z, 2, 1, 3)
109}
110
111func p8() {
112	m := make(map[int]int)
113	m[0] = len(m)
114	if m[0] != 0 {
115		panic(m[0])
116	}
117}
118
119// Issue #13433: Left-to-right assignment of OAS2XXX nodes.
120func p9() {
121	var x bool
122
123	// OAS2FUNC
124	x, x = fn()
125	checkOAS2XXX(x, "x, x = fn()")
126
127	// OAS2RECV
128	var c = make(chan bool, 10)
129	c <- false
130	x, x = <-c
131	checkOAS2XXX(x, "x, x <-c")
132
133	// OAS2MAPR
134	var m = map[int]bool{0: false}
135	x, x = m[0]
136	checkOAS2XXX(x, "x, x = m[0]")
137
138	// OAS2DOTTYPE
139	var i interface{} = false
140	x, x = i.(bool)
141	checkOAS2XXX(x, "x, x = i.(bool)")
142}
143
144//go:noinline
145func fn() (bool, bool) { return false, true }
146
147// checks the order of OAS2XXX.
148func checkOAS2XXX(x bool, s string) {
149	if !x {
150		fmt.Printf("%s; got=(false); want=(true)\n", s)
151		panic("failed")
152	}
153}
154
155//go:noinline
156func fp() (*int, int) { return nil, 42 }
157
158func p10() {
159	p := new(int)
160	p, *p = fp()
161}
162
163func p11() {
164	var i interface{}
165	p := new(bool)
166	p, *p = i.(*bool)
167}
168