blob: 8a184d1c6ad5753ed8d6beefb2c96a452daa8e64 [file] [log] [blame]
Brent Austinba3052e2015-04-21 16:08:23 -07001// runoutput
2
Dan Willemsen38f2dba2016-07-08 14:54:35 -07003// Copyright 2013 The Go Authors. All rights reserved.
Brent Austinba3052e2015-04-21 16:08:23 -07004// 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
9package main
10
11import (
12 "bufio"
13 "fmt"
14 "os"
15 "strconv"
16)
17
18var bout *bufio.Writer
19
20func 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
96var programTop = `
97package main
98
99import (
100 "fmt"
101 "os"
102 "unsafe"
103)
104
105var ok = true
106
107var (
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
122func notOK() {
123 if ok {
124 println("BUG:")
125 ok = false
126 }
127}
128
129func 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`