1// run
2
3// Copyright 2017 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// Issue 21687: cmd/compile evaluates x twice in "x op= y", which was
8// detectable if evaluating y affects x.
9
10package main
11
12func ptrs() (int, int) {
13	one := 1
14	two := 2
15
16	x := &one
17	*x += func() int {
18		x = &two
19		return 0
20	}()
21
22	return one, two
23}
24
25func slices() (int, int) {
26	one := []int{1}
27	two := []int{2}
28
29	x := one
30	x[0] += func() int {
31		x = two
32		return 0
33	}()
34
35	return one[0], two[0]
36}
37
38func maps() (int, int) {
39	one := map[int]int{0: 1}
40	two := map[int]int{0: 2}
41
42	x := one
43	x[0] += func() int {
44		x = two
45		return 0
46	}()
47
48	return one[0], two[0]
49}
50
51var tests = [...]func() (int, int){
52	ptrs,
53	slices,
54	maps,
55}
56
57func main() {
58	bad := 0
59	for i, f := range tests {
60		if a, b := f(); a+b != 3 {
61			println(i, a, b)
62			bad++
63		}
64	}
65	if bad != 0 {
66		panic(bad)
67	}
68}
69