diff options
author | Russ Cox <rsc@golang.org> | 2014-05-19 09:36:47 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-05-19 09:36:47 -0400 |
commit | d54b67df0cc2f9cfa7785919e20d152305bd72e8 (patch) | |
tree | f9845b42aa8d2cd7a19764a48c4cceabd5fa4e88 | |
parent | e893acf1848b96a922356eb753e8cea79f469afd (diff) | |
download | go-d54b67df0cc2f9cfa7785919e20d152305bd72e8.tar.gz go-d54b67df0cc2f9cfa7785919e20d152305bd72e8.zip |
reflect: test, fix access to nil maps
Fixes #8010.
LGTM=bradfitz, khr
R=khr, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/91450048
-rw-r--r-- | src/pkg/reflect/all_test.go | 22 | ||||
-rw-r--r-- | src/pkg/runtime/hashmap.goc | 12 |
2 files changed, 30 insertions, 4 deletions
diff --git a/src/pkg/reflect/all_test.go b/src/pkg/reflect/all_test.go index 1e6341bd0b..9c5eb4e554 100644 --- a/src/pkg/reflect/all_test.go +++ b/src/pkg/reflect/all_test.go @@ -973,6 +973,28 @@ func TestMap(t *testing.T) { } } +func TestNilMap(t *testing.T) { + var m map[string]int + mv := ValueOf(m) + keys := mv.MapKeys() + if len(keys) != 0 { + t.Errorf(">0 keys for nil map: %v", keys) + } + + // Check that value for missing key is zero. + x := mv.MapIndex(ValueOf("hello")) + if x.Kind() != Invalid { + t.Errorf("m.MapIndex(\"hello\") for nil map = %v, want Invalid Value", x) + } + + // Check big value too. + var mbig map[string][10 << 20]byte + x = ValueOf(mbig).MapIndex(ValueOf("hello")) + if x.Kind() != Invalid { + t.Errorf("mbig.MapIndex(\"hello\") for nil map = %v, want Invalid Value", x) + } +} + func TestChan(t *testing.T) { for loop := 0; loop < 2; loop++ { var c chan int diff --git a/src/pkg/runtime/hashmap.goc b/src/pkg/runtime/hashmap.goc index 4f5e78897b..36707c6ede 100644 --- a/src/pkg/runtime/hashmap.goc +++ b/src/pkg/runtime/hashmap.goc @@ -908,11 +908,15 @@ func mapaccess2(t *MapType, h *Hmap, key *byte) (val *byte, pres bool) { #pragma textflag NOSPLIT func reflect·mapaccess(t *MapType, h *Hmap, key *byte) (val *byte) { - if(raceenabled && h != nil) { - runtime·racereadpc(h, runtime·getcallerpc(&t), reflect·mapaccess); - runtime·racereadobjectpc(key, t->key, runtime·getcallerpc(&t), reflect·mapaccess); + if(h == nil) + val = nil; + else { + if(raceenabled) { + runtime·racereadpc(h, runtime·getcallerpc(&t), reflect·mapaccess); + runtime·racereadobjectpc(key, t->key, runtime·getcallerpc(&t), reflect·mapaccess); + } + val = hash_lookup(t, h, &key); } - val = hash_lookup(t, h, &key); } #pragma textflag NOSPLIT |