1// run
2
3// Copyright 2018 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// Ensure that range loops over maps with delete statements
8// have the requisite side-effects.
9
10package main
11
12import (
13	"fmt"
14	"os"
15)
16
17func checkcleared() {
18	m := make(map[byte]int)
19	m[1] = 1
20	m[2] = 2
21	for k := range m {
22		delete(m, k)
23	}
24	l := len(m)
25	if want := 0; l != want {
26		fmt.Printf("len after map clear = %d want %d\n", l, want)
27		os.Exit(1)
28	}
29
30	m[0] = 0 // To have non empty map and avoid internal map code fast paths.
31	n := 0
32	for range m {
33		n++
34	}
35	if want := 1; n != want {
36		fmt.Printf("number of keys found = %d want %d\n", n, want)
37		os.Exit(1)
38	}
39}
40
41func checkloopvars() {
42	k := 0
43	m := make(map[int]int)
44	m[42] = 0
45	for k = range m {
46		delete(m, k)
47	}
48	if want := 42; k != want {
49		fmt.Printf("var after range with side-effect = %d want %d\n", k, want)
50		os.Exit(1)
51	}
52}
53
54func checksideeffects() {
55	var x int
56	f := func() int {
57		x++
58		return 0
59	}
60	m := make(map[int]int)
61	m[0] = 0
62	m[1] = 1
63	for k := range m {
64		delete(m, k+f())
65	}
66	if want := 2; x != want {
67		fmt.Printf("var after range with side-effect = %d want %d\n", x, want)
68		os.Exit(1)
69	}
70
71	var n int
72	m = make(map[int]int)
73	m[0] = 0
74	m[1] = 1
75	for k := range m {
76		delete(m, k)
77		n++
78	}
79	if want := 2; n != want {
80		fmt.Printf("counter for range with side-effect = %d want %d\n", n, want)
81		os.Exit(1)
82	}
83}
84
85func main() {
86	checkcleared()
87	checkloopvars()
88	checksideeffects()
89}
90