]> Cypherpunks.ru repositories - gostls13.git/blobdiff - test/nil.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / nil.go
index 4f4c75527606d5ad0d7c34d1127cdc8a41aa5e0c..f8300bf56afb4f9135ef490f4a36ce0e35fb186e 100644 (file)
@@ -1,11 +1,18 @@
-// $G $F.go && $L $F.$A && ./$A.out
+// run
 
 // Copyright 2009 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 nil.
+
 package main
 
+import (
+       "fmt"
+       "time"
+)
+
 type T struct {
        i int
 }
@@ -33,4 +40,141 @@ func main() {
        ta[0] = nil
 
        _, _, _, _, _, _, _, _ = i, f, s, m, c, t, in, ta
+
+       arraytest()
+       chantest()
+       maptest()
+       slicetest()
+}
+
+func shouldPanic(f func()) {
+       defer func() {
+               if recover() == nil {
+                       panic("not panicking")
+               }
+       }()
+       f()
+}
+
+func shouldBlock(f func()) {
+       go func() {
+               f()
+               panic("did not block")
+       }()
+       time.Sleep(1e7)
+}
+
+// nil array pointer
+
+func arraytest() {
+       var p *[10]int
+
+       // Looping over indices is fine.
+       s := 0
+       for i := range p {
+               s += i
+       }
+       if s != 45 {
+               panic(s)
+       }
+
+       s = 0
+       for i := 0; i < len(p); i++ {
+               s += i
+       }
+       if s != 45 {
+               panic(s)
+       }
+
+       // Looping over values is not.
+       shouldPanic(func() {
+               for i, v := range p {
+                       s += i + v
+               }
+       })
+
+       shouldPanic(func() {
+               for i := 0; i < len(p); i++ {
+                       s += p[i]
+               }
+       })
+}
+
+// nil channel
+// select tests already handle select on nil channel
+
+func chantest() {
+       var ch chan int
+
+       // nil channel is never ready
+       shouldBlock(func() {
+               ch <- 1
+       })
+       shouldBlock(func() {
+               <-ch
+       })
+       shouldBlock(func() {
+               x, ok := <-ch
+               println(x, ok) // unreachable
+       })
+
+       if len(ch) != 0 {
+               panic(len(ch))
+       }
+       if cap(ch) != 0 {
+               panic(cap(ch))
+       }
+}
+
+// nil map
+
+func maptest() {
+       var m map[int]int
+
+       // nil map appears empty
+       if len(m) != 0 {
+               panic(len(m))
+       }
+       if m[1] != 0 {
+               panic(m[1])
+       }
+       if x, ok := m[1]; x != 0 || ok {
+               panic(fmt.Sprint(x, ok))
+       }
+
+       for k, v := range m {
+               panic(k)
+               panic(v)
+       }
+
+       // can delete (non-existent) entries
+       delete(m, 2)
+
+       // but cannot be written to
+       shouldPanic(func() {
+               m[2] = 3
+       })
+}
+
+// nil slice
+
+func slicetest() {
+       var x []int
+
+       // nil slice is just a 0-element slice.
+       if len(x) != 0 {
+               panic(len(x))
+       }
+       if cap(x) != 0 {
+               panic(cap(x))
+       }
+
+       // no 0-element slices can be read from or written to
+       var s int
+       shouldPanic(func() {
+               s += x[1]
+       })
+       shouldPanic(func() {
+               x[2] = s
+       })
 }