Home | History | Annotate | Download | only in test
      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 `
    161