if h.flags&hashWriting != 0 {
throw("concurrent map writes")
}
- h.flags |= hashWriting
-
alg := t.key.alg
hash := alg.hash(key, uintptr(h.hash0))
+ // Set hashWriting after calling alg.hash, since alg.hash may panic,
+ // in which case we have not actually done a write.
+ h.flags |= hashWriting
+
if h.buckets == nil {
h.buckets = newarray(t.bucket, 1)
}
if h.flags&hashWriting != 0 {
throw("concurrent map writes")
}
- h.flags |= hashWriting
alg := t.key.alg
hash := alg.hash(key, uintptr(h.hash0))
+
+ // Set hashWriting after calling alg.hash, since alg.hash may panic,
+ // in which case we have not actually done a write (delete).
+ h.flags |= hashWriting
+
bucket := hash & (uintptr(1)<<h.B - 1)
if h.growing() {
growWork(t, h, bucket)
--- /dev/null
+// 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.
+
+package main
+
+import "fmt"
+
+func set(m map[interface{}]interface{}, key interface{}) (err error) {
+ defer func() {
+ if r := recover(); r != nil {
+ err = fmt.Errorf("set failed: %v", r)
+ }
+ }()
+ m[key] = nil
+ return nil
+}
+
+func del(m map[interface{}]interface{}, key interface{}) (err error) {
+ defer func() {
+ if r := recover(); r != nil {
+ err = fmt.Errorf("del failed: %v", r)
+ }
+ }()
+ delete(m, key)
+ return nil
+}
+
+func main() {
+ m := make(map[interface{}]interface{})
+ set(m, []int{1, 2, 3})
+ set(m, "abc") // used to throw
+ del(m, []int{1, 2, 3})
+ del(m, "abc") // used to throw
+}