Source file test/makeslice.go

     1  // run
     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  package main
     8  
     9  import (
    10  	"strings"
    11  	"unsafe"
    12  )
    13  
    14  func main() {
    15  	n := -1
    16  	testInts(uint64(n))
    17  	testBytes(uint64(n))
    18  
    19  	var t *byte
    20  	if unsafe.Sizeof(t) == 8 {
    21  		// Test mem > maxAlloc
    22  		testInts(1 << 59)
    23  
    24  		// Test elem.size*cap overflow
    25  		testInts(1<<63 - 1)
    26  
    27  		testInts(1<<64 - 1)
    28  		testBytes(1<<64 - 1)
    29  	} else {
    30  		testInts(1<<31 - 1)
    31  
    32  		// Test elem.size*cap overflow
    33  		testInts(1<<32 - 1)
    34  		testBytes(1<<32 - 1)
    35  	}
    36  }
    37  
    38  func shouldPanic(str string, f func()) {
    39  	defer func() {
    40  		err := recover()
    41  		if err == nil {
    42  			panic("did not panic")
    43  		}
    44  		s := err.(error).Error()
    45  		if !strings.Contains(s, str) {
    46  			panic("got panic " + s + ", want " + str)
    47  		}
    48  	}()
    49  
    50  	f()
    51  }
    52  
    53  func testInts(n uint64) {
    54  	testMakeInts(n)
    55  	testMakeCopyInts(n)
    56  	testMakeInAppendInts(n)
    57  }
    58  
    59  func testBytes(n uint64) {
    60  	testMakeBytes(n)
    61  	testMakeCopyBytes(n)
    62  	testMakeInAppendBytes(n)
    63  }
    64  
    65  // Test make panics for given length or capacity n.
    66  func testMakeInts(n uint64) {
    67  	type T []int
    68  	shouldPanic("len out of range", func() { _ = make(T, int(n)) })
    69  	shouldPanic("cap out of range", func() { _ = make(T, 0, int(n)) })
    70  	shouldPanic("len out of range", func() { _ = make(T, uint(n)) })
    71  	shouldPanic("cap out of range", func() { _ = make(T, 0, uint(n)) })
    72  	shouldPanic("len out of range", func() { _ = make(T, int64(n)) })
    73  	shouldPanic("cap out of range", func() { _ = make(T, 0, int64(n)) })
    74  	shouldPanic("len out of range", func() { _ = make(T, uint64(n)) })
    75  	shouldPanic("cap out of range", func() { _ = make(T, 0, uint64(n)) })
    76  }
    77  
    78  func testMakeBytes(n uint64) {
    79  	type T []byte
    80  	shouldPanic("len out of range", func() { _ = make(T, int(n)) })
    81  	shouldPanic("cap out of range", func() { _ = make(T, 0, int(n)) })
    82  	shouldPanic("len out of range", func() { _ = make(T, uint(n)) })
    83  	shouldPanic("cap out of range", func() { _ = make(T, 0, uint(n)) })
    84  	shouldPanic("len out of range", func() { _ = make(T, int64(n)) })
    85  	shouldPanic("cap out of range", func() { _ = make(T, 0, int64(n)) })
    86  	shouldPanic("len out of range", func() { _ = make(T, uint64(n)) })
    87  	shouldPanic("cap out of range", func() { _ = make(T, 0, uint64(n)) })
    88  }
    89  
    90  // Test make+copy panics since the gc compiler optimizes these
    91  // to runtime.makeslicecopy calls.
    92  func testMakeCopyInts(n uint64) {
    93  	type T []int
    94  	var c = make(T, 8)
    95  	shouldPanic("len out of range", func() { x := make(T, int(n)); copy(x, c) })
    96  	shouldPanic("cap out of range", func() { x := make(T, 0, int(n)); copy(x, c) })
    97  	shouldPanic("len out of range", func() { x := make(T, uint(n)); copy(x, c) })
    98  	shouldPanic("cap out of range", func() { x := make(T, 0, uint(n)); copy(x, c) })
    99  	shouldPanic("len out of range", func() { x := make(T, int64(n)); copy(x, c) })
   100  	shouldPanic("cap out of range", func() { x := make(T, 0, int64(n)); copy(x, c) })
   101  	shouldPanic("len out of range", func() { x := make(T, uint64(n)); copy(x, c) })
   102  	shouldPanic("cap out of range", func() { x := make(T, 0, uint64(n)); copy(x, c) })
   103  }
   104  
   105  func testMakeCopyBytes(n uint64) {
   106  	type T []byte
   107  	var c = make(T, 8)
   108  	shouldPanic("len out of range", func() { x := make(T, int(n)); copy(x, c) })
   109  	shouldPanic("cap out of range", func() { x := make(T, 0, int(n)); copy(x, c) })
   110  	shouldPanic("len out of range", func() { x := make(T, uint(n)); copy(x, c) })
   111  	shouldPanic("cap out of range", func() { x := make(T, 0, uint(n)); copy(x, c) })
   112  	shouldPanic("len out of range", func() { x := make(T, int64(n)); copy(x, c) })
   113  	shouldPanic("cap out of range", func() { x := make(T, 0, int64(n)); copy(x, c) })
   114  	shouldPanic("len out of range", func() { x := make(T, uint64(n)); copy(x, c) })
   115  	shouldPanic("cap out of range", func() { x := make(T, 0, uint64(n)); copy(x, c) })
   116  }
   117  
   118  // Test make in append panics for int slices since the gc compiler optimizes makes in appends.
   119  func testMakeInAppendInts(n uint64) {
   120  	type T []int
   121  	for _, length := range []int{0, 1} {
   122  		t := make(T, length)
   123  		shouldPanic("len out of range", func() { _ = append(t, make(T, int(n))...) })
   124  		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int(n))...) })
   125  		shouldPanic("len out of range", func() { _ = append(t, make(T, int64(n))...) })
   126  		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int64(n))...) })
   127  		shouldPanic("len out of range", func() { _ = append(t, make(T, uint64(n))...) })
   128  		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint64(n))...) })
   129  		shouldPanic("len out of range", func() { _ = append(t, make(T, int(n))...) })
   130  		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int(n))...) })
   131  		shouldPanic("len out of range", func() { _ = append(t, make(T, uint(n))...) })
   132  		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint(n))...) })
   133  	}
   134  }
   135  
   136  func testMakeInAppendBytes(n uint64) {
   137  	type T []byte
   138  	for _, length := range []int{0, 1} {
   139  		t := make(T, length)
   140  		shouldPanic("len out of range", func() { _ = append(t, make(T, int(n))...) })
   141  		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int(n))...) })
   142  		shouldPanic("len out of range", func() { _ = append(t, make(T, uint(n))...) })
   143  		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint(n))...) })
   144  		shouldPanic("len out of range", func() { _ = append(t, make(T, int64(n))...) })
   145  		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int64(n))...) })
   146  		shouldPanic("len out of range", func() { _ = append(t, make(T, uint64(n))...) })
   147  		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint64(n))...) })
   148  	}
   149  }
   150  

View as plain text