// run // Copyright 2017 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Test to make sure RHS is evaluated before map insert is started. // The RHS panics in all of these cases. package main import "fmt" func main() { for i, f := range []func(map[int]int){ f0, f1, f2, f3, f4, f5, f6, f7, f8, } { m := map[int]int{} func() { // wrapper to scope the defer. defer func() { recover() }() f(m) // Will panic. Shouldn't modify m. fmt.Printf("RHS didn't panic, case f%d\n", i) }() if len(m) != 0 { fmt.Printf("map insert happened, case f%d\n", i) } } // Append slice. for i, f := range []func(map[int][]int){ fa0, fa1, fa2, fa3, } { m := map[int][]int{} func() { // wrapper to scope the defer. defer func() { recover() }() f(m) // Will panic. Shouldn't modify m. fmt.Printf("RHS didn't panic, case fa%d\n", i) }() if len(m) != 0 { fmt.Printf("map insert happened, case fa%d\n", i) } } } func f0(m map[int]int) { var p *int m[0] = *p } func f1(m map[int]int) { var p *int m[0] += *p } func f2(m map[int]int) { var p *int sink, m[0] = sink, *p } func f3(m map[int]int) { var p *chan int m[0], sink = <-(*p) } func f4(m map[int]int) { var p *interface{} m[0], sink = (*p).(int) } func f5(m map[int]int) { var p *map[int]int m[0], sink = (*p)[0] } func f6(m map[int]int) { var z int m[0] /= z } func f7(m map[int]int) { var a []int m[0] = a[0] } func f8(m map[int]int) { var z int m[0] %= z } func fa0(m map[int][]int) { var p *int m[0] = append(m[0], *p) } func fa1(m map[int][]int) { var p *int sink, m[0] = !sink, append(m[0], *p) } func fa2(m map[int][]int) { var p *int m[0], _ = append(m[0], 0), *p } func fa3(m map[int][]int) { // OSLICE has similar in-place-reassignment // optimizations as OAPPEND, but we need to make sure // to *not* optimize them, because we can't guarantee // the slice indices are within bounds. m[0] = m[0][:1] } var sink bool