From e99b8a24fe54a9e2859265bc970f9885e748e208 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 29 Oct 2020 16:51:05 +0100 Subject: [PATCH] runtime: allow ranging over a nil map This appears to be allowed by the specification, at least it is allowed by the main Go implementation: https://play.golang.org/p/S8jxAMytKDB Allow it in TinyGo too, for consistency. Found because it is triggered with `tinygo test flags`. This doesn't make the flags package pass all tests, but is a step closer. --- src/runtime/hashmap.go | 7 +++++++ testdata/map.go | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go index d7d60c89..136fb36b 100644 --- a/src/runtime/hashmap.go +++ b/src/runtime/hashmap.go @@ -261,6 +261,13 @@ func hashmapDelete(m *hashmap, key unsafe.Pointer, hash uint32, keyEqual func(x, // Iterate over a hashmap. //go:nobounds func hashmapNext(m *hashmap, it *hashmapIterator, key, value unsafe.Pointer) bool { + if m == nil { + // Iterating over a nil slice appears to be allowed by the Go spec: + // https://groups.google.com/g/golang-nuts/c/gVgVLQU1FFE?pli=1 + // https://play.golang.org/p/S8jxAMytKDB + return false + } + numBuckets := uintptr(1) << m.bucketBits for { if it.bucketIndex >= 8 { diff --git a/testdata/map.go b/testdata/map.go index b0230eb9..b93eacac 100644 --- a/testdata/map.go +++ b/testdata/map.go @@ -49,6 +49,9 @@ func main() { println(testmapIntInt[2]) testmapIntInt[2] = 42 println(testmapIntInt[2]) + for k := range nilmap { + println(k) // unreachable + } arrKey := ArrayKey([4]byte{4, 3, 2, 1}) println(testMapArrayKey[arrKey])