modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/slice3.go (about) 1 // runoutput 2 3 // Copyright 2013 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 // Test run-time behavior of 3-index slice expressions. 8 9 package main 10 11 import ( 12 "bufio" 13 "fmt" 14 "os" 15 "strconv" 16 ) 17 18 var bout *bufio.Writer 19 20 func main() { 21 bout = bufio.NewWriter(os.Stdout) 22 23 fmt.Fprintf(bout, "%s", programTop) 24 fmt.Fprintf(bout, "func main() {\n") 25 26 index := []string{ 27 "0", 28 "1", 29 "2", 30 "3", 31 "10", 32 "20", 33 "vminus1", 34 "v0", 35 "v1", 36 "v2", 37 "v3", 38 "v10", 39 "v20", 40 } 41 42 parse := func(s string) (n int, isconst bool) { 43 if s == "vminus1" { 44 return -1, false 45 } 46 isconst = true 47 if s[0] == 'v' { 48 isconst = false 49 s = s[1:] 50 } 51 n, _ = strconv.Atoi(s) 52 return n, isconst 53 } 54 55 const Cap = 10 // cap of slice, array 56 57 for _, base := range []string{"array", "slice"} { 58 for _, i := range index { 59 iv, iconst := parse(i) 60 for _, j := range index { 61 jv, jconst := parse(j) 62 for _, k := range index { 63 kv, kconst := parse(k) 64 // Avoid errors that would make the program not compile. 65 // Those are tested by slice3err.go. 66 switch { 67 case iconst && jconst && iv > jv, 68 jconst && kconst && jv > kv, 69 iconst && kconst && iv > kv, 70 iconst && base == "array" && iv > Cap, 71 jconst && base == "array" && jv > Cap, 72 kconst && base == "array" && kv > Cap: 73 continue 74 } 75 76 expr := base + "[" + i + ":" + j + ":" + k + "]" 77 var xbase, xlen, xcap int 78 if iv > jv || jv > kv || kv > Cap || iv < 0 || jv < 0 || kv < 0 { 79 xbase, xlen, xcap = -1, -1, -1 80 } else { 81 xbase = iv 82 xlen = jv - iv 83 xcap = kv - iv 84 } 85 fmt.Fprintf(bout, "\tcheckSlice(%q, func() []byte { return %s }, %d, %d, %d)\n", expr, expr, xbase, xlen, xcap) 86 } 87 } 88 } 89 } 90 91 fmt.Fprintf(bout, "\tif !ok { os.Exit(1) }\n") 92 fmt.Fprintf(bout, "}\n") 93 bout.Flush() 94 } 95 96 var programTop = ` 97 package main 98 99 import ( 100 "fmt" 101 "os" 102 "unsafe" 103 ) 104 105 var ok = true 106 107 var ( 108 array = new([10]byte) 109 slice = array[:] 110 111 vminus1 = -1 112 v0 = 0 113 v1 = 1 114 v2 = 2 115 v3 = 3 116 v4 = 4 117 v5 = 5 118 v10 = 10 119 v20 = 20 120 ) 121 122 func notOK() { 123 if ok { 124 println("BUG:") 125 ok = false 126 } 127 } 128 129 func checkSlice(desc string, f func() []byte, xbase, xlen, xcap int) { 130 defer func() { 131 if err := recover(); err != nil { 132 if xbase >= 0 { 133 notOK() 134 println(desc, " unexpected panic: ", fmt.Sprint(err)) 135 } 136 } 137 // "no panic" is checked below 138 }() 139 140 x := f() 141 142 arrayBase := uintptr(unsafe.Pointer(array)) 143 raw := *(*[3]uintptr)(unsafe.Pointer(&x)) 144 base, len, cap := raw[0] - arrayBase, raw[1], raw[2] 145 if xbase < 0 { 146 notOK() 147 println(desc, "=", base, len, cap, "want panic") 148 return 149 } 150 if cap != 0 && base != uintptr(xbase) || base >= 10 || len != uintptr(xlen) || cap != uintptr(xcap) { 151 notOK() 152 if cap == 0 { 153 println(desc, "=", base, len, cap, "want", "0-9", xlen, xcap) 154 } else { 155 println(desc, "=", base, len, cap, "want", xbase, xlen, xcap) 156 } 157 } 158 } 159 160 `