Source file test/slice3.go

     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  

View as plain text