1
// $G $D/$F.go && $L $F.$A &&
2
// ./$A.out -pass 0 >tmp.go && $G tmp.go && $L -o $A.out1 tmp.$A && ./$A.out1 &&
3
// ./$A.out -pass 1 >tmp.go && errchk $G -e tmp.go &&
4
// ./$A.out -pass 2 >tmp.go && errchk $G -e tmp.go
5
// rm -f tmp.go $A.out1
7
3
// Copyright 2010 The Go Authors. All rights reserved.
8
4
// Use of this source code is governed by a BSD-style
9
5
// license that can be found in the LICENSE file.
11
7
// Generate test of index and slice bounds checks.
12
// The output is compiled and run.
8
// The actual tests are index0.go, index1.go, index2.go.
158
// pass variable set in index[012].go
155
159
// 0 - dynamic checks
156
160
// 1 - static checks of invalid constants (cannot assign to types)
157
161
// 2 - static checks of array bounds
158
var pass = flag.Int("pass", 0, "which test (0,1,2)")
160
163
func testExpr(b *bufio.Writer, expr string) {
162
165
fmt.Fprintf(b, "\ttest(func(){use(%s)}, %q)\n", expr, expr)
164
fmt.Fprintf(b, "\tuse(%s) // ERROR \"index|overflow\"\n", expr)
167
fmt.Fprintf(b, "\tuse(%s) // ERROR \"index|overflow|truncated\"\n", expr)
169
172
b := bufio.NewWriter(os.Stdout)
174
fmt.Fprint(b, "// $G $D/$F.go && $L $F.$A && ./$A.out\n\n")
175
fmt.Fprint(b, "// run\n\n")
176
fmt.Fprint(b, "// errchk $G -e $D/$F.go\n\n")
177
fmt.Fprint(b, "// errorcheck\n\n")
178
179
fmt.Fprint(b, prolog)
180
181
var choices = [][]string{
181
182
// Direct value, fetch from struct, fetch from struct pointer.
182
183
// The last two cases get us to oindex_const_sudo in gsubr.c.
183
184
[]string{"", "t.", "pt."},
185
186
// Array, pointer to array, slice.
186
187
[]string{"a", "pa", "s"},
188
189
// Element is int, element is quad (struct).
189
190
// This controls whether we end up in gsubr.c (i) or cgen.c (q).
190
191
[]string{"i", "q"},
199
200
[]string{"", "n"},
201
202
// Size of index.
202
[]string{"j", "i", "i8", "i16", "i32", "i64", "i64big", "i64bigger", "huge"},
203
[]string{"j", "i", "i8", "i16", "i32", "i64", "i64big", "i64bigger", "huge", "fgood", "fbad"},
205
206
forall(choices, func(x []string) {
206
207
p, a, e, big, c, n, i := x[0], x[1], x[2], x[3], x[4], x[5], x[6]
221
222
// the next pass from running.
222
223
// So run it as a separate check.
225
} else if a == "s" && n == "" && (i == "i64big" || i == "i64bigger") && unsafe.Sizeof(int(0)) > 4 {
226
// If int is 64 bits, these huge
227
// numbers do fit in an int, so they
228
// are not rejected at compile time.
235
pae := p + a + e + big
229
238
// If we're using the big-len data, positive int8 and int16 cannot overflow.
230
239
if big == "b" && n == "" && (i == "i8" || i == "i16") {
241
fmt.Fprintf(b, "\tuse(%s[%s])\n", pae, cni)
242
fmt.Fprintf(b, "\tuse(%s[0:%s])\n", pae, cni)
243
fmt.Fprintf(b, "\tuse(%s[1:%s])\n", pae, cni)
244
fmt.Fprintf(b, "\tuse(%s[%s:])\n", pae, cni)
245
fmt.Fprintf(b, "\tuse(%s[%s:%s])\n", pae, cni, cni)
250
// Float variables cannot be used as indices.
251
if c == "" && (i == "fgood" || i == "fbad") {
254
// Integral float constat is ok.
255
if c == "c" && n == "" && i == "fgood" {
257
fmt.Fprintf(b, "\tuse(%s[%s])\n", pae, cni)
258
fmt.Fprintf(b, "\tuse(%s[0:%s])\n", pae, cni)
259
fmt.Fprintf(b, "\tuse(%s[1:%s])\n", pae, cni)
260
fmt.Fprintf(b, "\tuse(%s[%s:])\n", pae, cni)
261
fmt.Fprintf(b, "\tuse(%s[%s:%s])\n", pae, cni, cni)
234
266
// Only print the test case if it is appropriate for this pass.
235
if thisPass == *pass {
267
if thisPass == pass {
239
268
// Index operation
240
testExpr(b, pae + "[" + cni + "]")
269
testExpr(b, pae+"["+cni+"]")
242
271
// Slice operation.
243
272
// Low index 0 is a special case in ggen.c
244
273
// so test both 0 and 1.
245
testExpr(b, pae + "[0:" + cni + "]")
246
testExpr(b, pae + "[1:" + cni + "]")
247
testExpr(b, pae + "[" + cni + ":]")
248
testExpr(b, pae + "[" + cni + ":" + cni + "]")
274
testExpr(b, pae+"[0:"+cni+"]")
275
testExpr(b, pae+"[1:"+cni+"]")
276
testExpr(b, pae+"["+cni+":]")
277
testExpr(b, pae+"["+cni+":"+cni+"]")