1// run
2
3// Copyright 2010 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 reorderings; derived from fixedbugs/bug294.go.
8
9package main
10
11var log string
12
13type TT int
14
15func (t TT) a(s string) TT {
16	log += "a(" + s + ")"
17	return t
18}
19
20func (TT) b(s string) string {
21	log += "b(" + s + ")"
22	return s
23}
24
25type F func(s string) F
26
27func a(s string) F {
28	log += "a(" + s + ")"
29	return F(a)
30}
31
32func b(s string) string {
33	log += "b(" + s + ")"
34	return s
35}
36
37type I interface {
38	a(s string) I
39	b(s string) string
40}
41
42type T1 int
43
44func (t T1) a(s string) I {
45	log += "a(" + s + ")"
46	return t
47}
48
49func (T1) b(s string) string {
50	log += "b(" + s + ")"
51	return s
52}
53
54// f(g(), h()) where g is not inlinable but h is will have the same problem.
55// As will x := g() + h() (same conditions).
56// And g() <- h().
57func f(x, y string) {
58	log += "f(" + x + ", " + y + ")"
59}
60
61//go:noinline
62func ff(x, y string) {
63	log += "ff(" + x + ", " + y + ")"
64}
65
66func h(x string) string {
67	log += "h(" + x + ")"
68	return x
69}
70
71//go:noinline
72func g(x string) string {
73	log += "g(" + x + ")"
74	return x
75}
76
77func main() {
78	err := 0
79	var t TT
80	if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
81		println("expecting a(1)a(2)a(3) , got ", log)
82		err++
83	}
84	log = ""
85
86	if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
87		println("expecting a(1)b(2)a(2), got ", log)
88		err++
89	}
90	log = ""
91	if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
92		println("expecting a(3)b(4)a(4)b(5)a(5), got ", log)
93		err++
94	}
95	log = ""
96	var i I = T1(0)
97	if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
98		println("expecting a(6)ba(7)ba(8)ba(9), got", log)
99		err++
100	}
101	log = ""
102
103	if s := t.a("1").b("3"); log != "a(1)b(3)" || s != "3" {
104		println("expecting a(1)b(3) and 3, got ", log, " and ", s)
105		err++
106	}
107	log = ""
108
109	if s := t.a("1").a(t.b("2")).b("3") + t.a("4").b("5"); log != "a(1)b(2)a(2)b(3)a(4)b(5)" || s != "35" {
110		println("expecting a(1)b(2)a(2)b(3)a(4)b(5) and 35, got ", log, " and ", s)
111		err++
112	}
113	log = ""
114
115	if s := t.a("4").b("5") + t.a("1").a(t.b("2")).b("3"); log != "a(4)b(5)a(1)b(2)a(2)b(3)" || s != "53" {
116		println("expecting a(4)b(5)a(1)b(2)a(2)b(3) and 35, got ", log, " and ", s)
117		err++
118	}
119	log = ""
120
121	if ff(g("1"), g("2")); log != "g(1)g(2)ff(1, 2)" {
122		println("expecting g(1)g(2)ff..., got ", log)
123		err++
124	}
125	log = ""
126
127	if ff(g("1"), h("2")); log != "g(1)h(2)ff(1, 2)" {
128		println("expecting g(1)h(2)ff..., got ", log)
129		err++
130	}
131	log = ""
132
133	if ff(h("1"), g("2")); log != "h(1)g(2)ff(1, 2)" {
134		println("expecting h(1)g(2)ff..., got ", log)
135		err++
136	}
137	log = ""
138
139	if ff(h("1"), h("2")); log != "h(1)h(2)ff(1, 2)" {
140		println("expecting h(1)h(2)ff..., got ", log)
141		err++
142	}
143	log = ""
144
145	if s := g("1") + g("2"); log != "g(1)g(2)" || s != "12" {
146		println("expecting g1g2 and 12, got ", log, " and ", s)
147		err++
148	}
149	log = ""
150
151	if s := g("1") + h("2"); log != "g(1)h(2)" || s != "12" {
152		println("expecting g1h2 and 12, got ", log, " and ", s)
153		err++
154	}
155	log = ""
156
157	if s := h("1") + g("2"); log != "h(1)g(2)" || s != "12" {
158		println("expecting h1g2 and 12, got ", log, " and ", s)
159		err++
160	}
161	log = ""
162
163	if s := h("1") + h("2"); log != "h(1)h(2)" || s != "12" {
164		println("expecting h1h2 and 12, got ", log, " and ", s)
165		err++
166	}
167	log = ""
168
169	x := 0
170	switch x {
171	case 0:
172		if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
173			println("in switch, expecting a(1)a(2)a(3) , got ", log)
174			err++
175		}
176		log = ""
177
178		if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
179			println("in switch, expecting a(1)b(2)a(2), got ", log)
180			err++
181		}
182		log = ""
183		if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
184			println("in switch, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
185			err++
186		}
187		log = ""
188		var i I = T1(0)
189		if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
190			println("in switch, expecting a(6)ba(7)ba(8)ba(9), got", log)
191			err++
192		}
193		log = ""
194	}
195
196	c := make(chan int, 1)
197	c <- 1
198	select {
199	case c <- 0:
200	case c <- 1:
201	case <-c:
202		if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
203			println("in select1, expecting a(1)a(2)a(3) , got ", log)
204			err++
205		}
206		log = ""
207
208		if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
209			println("in select1, expecting a(1)b(2)a(2), got ", log)
210			err++
211		}
212		log = ""
213		if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
214			println("in select1, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
215			err++
216		}
217		log = ""
218		var i I = T1(0)
219		if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
220			println("in select1, expecting a(6)ba(7)ba(8)ba(9), got", log)
221			err++
222		}
223		log = ""
224	}
225
226	c <- 1
227	select {
228	case <-c:
229		if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
230			println("in select2, expecting a(1)a(2)a(3) , got ", log)
231			err++
232		}
233		log = ""
234
235		if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
236			println("in select2, expecting a(1)b(2)a(2), got ", log)
237			err++
238		}
239		log = ""
240		if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
241			println("in select2, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
242			err++
243		}
244		log = ""
245		var i I = T1(0)
246		if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
247			println("in select2, expecting a(6)ba(7)ba(8)ba(9), got", log)
248			err++
249		}
250		log = ""
251	}
252
253	c <- 1
254	select {
255	default:
256	case c <- 1:
257	case <-c:
258		if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
259			println("in select3, expecting a(1)a(2)a(3) , got ", log)
260			err++
261		}
262		log = ""
263
264		if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
265			println("in select3, expecting a(1)b(2)a(2), got ", log)
266			err++
267		}
268		log = ""
269		if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
270			println("in select3, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
271			err++
272		}
273		log = ""
274		var i I = T1(0)
275		if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
276			println("in select3, expecting a(6)ba(7)ba(8)ba(9), got", log)
277			err++
278		}
279		log = ""
280	}
281
282	c <- 1
283	select {
284	default:
285	case <-c:
286		if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
287			println("in select4, expecting a(1)a(2)a(3) , got ", log)
288			err++
289		}
290		log = ""
291
292		if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
293			println("in select4, expecting a(1)b(2)a(2), got ", log)
294			err++
295		}
296		log = ""
297		if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
298			println("in select4, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
299			err++
300		}
301		log = ""
302		var i I = T1(0)
303		if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
304			println("in select4, expecting a(6)ba(7)ba(8)ba(9), got", log)
305			err++
306		}
307		log = ""
308	}
309
310	select {
311	case <-c:
312	case <-c:
313	default:
314		if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
315			println("in select5, expecting a(1)a(2)a(3) , got ", log)
316			err++
317		}
318		log = ""
319
320		if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
321			println("in select5, expecting a(1)b(2)a(2), got ", log)
322			err++
323		}
324		log = ""
325		if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
326			println("in select5, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
327			err++
328		}
329		log = ""
330		var i I = T1(0)
331		if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
332			println("in select5, expecting a(6)ba(7)ba(8)ba(9), got", log)
333			err++
334		}
335		log = ""
336	}
337
338	if err > 0 {
339		panic("fail")
340	}
341}
342