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// Test to make sure RHS is evaluated before map insert is started.
8// The RHS panics in all of these cases.
9
10package main
11
12import "fmt"
13
14func main() {
15	for i, f := range []func(map[int]int){
16		f0, f1, f2, f3, f4, f5, f6, f7, f8,
17	} {
18		m := map[int]int{}
19		func() { // wrapper to scope the defer.
20			defer func() {
21				recover()
22			}()
23			f(m) // Will panic. Shouldn't modify m.
24			fmt.Printf("RHS didn't panic, case f%d\n", i)
25		}()
26		if len(m) != 0 {
27			fmt.Printf("map insert happened, case f%d\n", i)
28		}
29	}
30
31	// Append slice.
32	for i, f := range []func(map[int][]int){
33		fa0, fa1, fa2, fa3,
34	} {
35		m := map[int][]int{}
36		func() { // wrapper to scope the defer.
37			defer func() {
38				recover()
39			}()
40			f(m) // Will panic. Shouldn't modify m.
41			fmt.Printf("RHS didn't panic, case fa%d\n", i)
42		}()
43		if len(m) != 0 {
44			fmt.Printf("map insert happened, case fa%d\n", i)
45		}
46	}
47}
48
49func f0(m map[int]int) {
50	var p *int
51	m[0] = *p
52}
53
54func f1(m map[int]int) {
55	var p *int
56	m[0] += *p
57}
58
59func f2(m map[int]int) {
60	var p *int
61	sink, m[0] = sink, *p
62}
63
64func f3(m map[int]int) {
65	var p *chan int
66	m[0], sink = <-(*p)
67}
68
69func f4(m map[int]int) {
70	var p *interface{}
71	m[0], sink = (*p).(int)
72}
73
74func f5(m map[int]int) {
75	var p *map[int]int
76	m[0], sink = (*p)[0]
77}
78
79func f6(m map[int]int) {
80	var z int
81	m[0] /= z
82}
83
84func f7(m map[int]int) {
85	var a []int
86	m[0] = a[0]
87}
88
89func f8(m map[int]int) {
90	var z int
91	m[0] %= z
92}
93
94func fa0(m map[int][]int) {
95	var p *int
96	m[0] = append(m[0], *p)
97}
98
99func fa1(m map[int][]int) {
100	var p *int
101	sink, m[0] = !sink, append(m[0], *p)
102}
103
104func fa2(m map[int][]int) {
105	var p *int
106	m[0], _ = append(m[0], 0), *p
107}
108
109func fa3(m map[int][]int) {
110	// OSLICE has similar in-place-reassignment
111	// optimizations as OAPPEND, but we need to make sure
112	// to *not* optimize them, because we can't guarantee
113	// the slice indices are within bounds.
114	m[0] = m[0][:1]
115}
116
117var sink bool
118