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
7package main
8
9import (
10	"strings"
11	"unsafe"
12)
13
14type T []int
15
16func main() {
17	n := -1
18	shouldPanic("len out of range", func() { _ = make(T, n) })
19	shouldPanic("cap out of range", func() { _ = make(T, 0, n) })
20	shouldPanic("len out of range", func() { _ = make(T, int64(n)) })
21	shouldPanic("cap out of range", func() { _ = make(T, 0, int64(n)) })
22	testMakeInAppend(n)
23
24	var t *byte
25	if unsafe.Sizeof(t) == 8 {
26		// Test mem > maxAlloc
27		var n2 int64 = 1 << 59
28		shouldPanic("len out of range", func() { _ = make(T, int(n2)) })
29		shouldPanic("cap out of range", func() { _ = make(T, 0, int(n2)) })
30		testMakeInAppend(int(n2))
31		// Test elem.size*cap overflow
32		n2 = 1<<63 - 1
33		shouldPanic("len out of range", func() { _ = make(T, int(n2)) })
34		shouldPanic("cap out of range", func() { _ = make(T, 0, int(n2)) })
35		testMakeInAppend(int(n2))
36		var x uint64 = 1<<64 - 1
37		shouldPanic("len out of range", func() { _ = make([]byte, x) })
38		shouldPanic("cap out of range", func() { _ = make(T, 0, x) })
39		testMakeInAppend(int(x))
40	} else {
41		n = 1<<31 - 1
42		shouldPanic("len out of range", func() { _ = make(T, n) })
43		shouldPanic("cap out of range", func() { _ = make(T, 0, n) })
44		shouldPanic("len out of range", func() { _ = make(T, int64(n)) })
45		shouldPanic("cap out of range", func() { _ = make(T, 0, int64(n)) })
46		testMakeInAppend(n)
47		var x uint64 = 1<<32 - 1
48		shouldPanic("len out of range", func() { _ = make([]byte, x) })
49		shouldPanic("cap out of range", func() { _ = make(T, 0, x) })
50		testMakeInAppend(int(x))
51	}
52}
53
54func shouldPanic(str string, f func()) {
55	defer func() {
56		err := recover()
57		if err == nil {
58			panic("did not panic")
59		}
60		s := err.(error).Error()
61		if !strings.Contains(s, str) {
62			panic("got panic " + s + ", want " + str)
63		}
64	}()
65
66	f()
67}
68
69// Test make in append panics since the gc compiler optimizes makes in appends.
70func testMakeInAppend(n int) {
71	lengths := []int{0, 1}
72	for _, length := range lengths {
73		t := make(T, length)
74		shouldPanic("len out of range", func() { _ = append(t, make(T, n)...) })
75		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, n)...) })
76		shouldPanic("len out of range", func() { _ = append(t, make(T, int64(n))...) })
77		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int64(n))...) })
78		shouldPanic("len out of range", func() { _ = append(t, make(T, uint64(n))...) })
79		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint64(n))...) })
80		shouldPanic("len out of range", func() { _ = append(t, make(T, int(n))...) })
81		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int(n))...) })
82		shouldPanic("len out of range", func() { _ = append(t, make(T, uint(n))...) })
83		shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint(n))...) })
84	}
85}
86