1 // +build amd64,!gcflags_noopt
2 // errorcheck -0 -d=ssa/check_bce/debug=3
4 // Copyright 2016 The Go Authors. All rights reserved.
5 // Use of this source code is governed by a BSD-style
6 // license that can be found in the LICENSE file.
8 // Test that the compiler does bounds check elimination as expected.
9 // This avoids accidental regressions.
14 a[0] = 1 // ERROR "Found IsInBounds$"
16 a[6] = 1 // ERROR "Found IsInBounds$"
22 func f1(a [256]int, i int) {
24 useInt(a[i]) // ERROR "Found IsInBounds$"
26 useInt(a[j]) // ERROR "Found IsInBounds$"
32 if 4 <= i && i < len(a) {
34 useInt(a[i-1]) // ERROR "Found IsInBounds$"
35 // TODO: 'if 4 <= i && i < len(a)' gets rewritten to 'if uint(i - 4) < 256 - 4',
36 // which the bounds checker cannot yet use to infer that the next line doesn't need a bounds check.
41 func f2(a [256]int, i uint) {
42 useInt(a[i]) // ERROR "Found IsInBounds$"
51 func f2a(a [35]int, i uint8) {
52 useInt(a[i]) // ERROR "Found IsInBounds$"
59 func f2b(a [35]int, i uint16) {
60 useInt(a[i]) // ERROR "Found IsInBounds$"
67 func f2c(a [35]int, i uint32) {
68 useInt(a[i]) // ERROR "Found IsInBounds$"
75 func f3(a [256]int, i uint8) {
81 func f4(a [27]int, i uint8) {
95 func f6(a [32]int, b [64]int, i int) {
96 useInt(a[uint32(i*0x07C4ACDD)>>27])
97 useInt(b[uint64(i*0x07C4ACDD)>>58])
98 useInt(a[uint(i*0x07C4ACDD)>>59])
100 // The following bounds should not be removed because they can overflow.
101 useInt(a[uint32(i*0x106297f105d0cc86)>>26]) // ERROR "Found IsInBounds$"
102 useInt(b[uint64(i*0x106297f105d0cc86)>>57]) // ERROR "Found IsInBounds$"
103 useInt(a[int32(i*0x106297f105d0cc86)>>26]) // ERROR "Found IsInBounds$"
104 useInt(b[int64(i*0x106297f105d0cc86)>>57]) // ERROR "Found IsInBounds$"
116 useInt(a[3]) // ERROR "Found IsInBounds$"
123 for i := range a[:256] { // ERROR "Found IsSliceInBounds$"
124 useInt(a[i]) // ERROR "Found IsInBounds$"
132 func g4(a [100]int) {
133 for i := 10; i < 50; i++ {
139 // The following are out of bounds.
140 useInt(a[i-11]) // ERROR "Found IsInBounds$"
141 useInt(a[i+51]) // ERROR "Found IsInBounds$"
145 func Uint64(b []byte) uint64 {
146 _ = b[7] // ERROR "Found IsInBounds$"
147 return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
148 uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
151 func decode1(data []byte) (x uint64) {
152 for len(data) >= 32 {
153 x += Uint64(data[:8])
154 x += Uint64(data[8:16])
155 x += Uint64(data[16:24])
156 x += Uint64(data[24:32])
162 func decode2(data []byte) (x uint64) {
163 // TODO(rasky): this should behave like decode1 and compile to no
164 // boundchecks. We're currently not able to remove all of them.
165 for len(data) >= 32 {
168 x += Uint64(data) // ERROR "Found IsInBounds$"
170 x += Uint64(data) // ERROR "Found IsInBounds$"
172 x += Uint64(data) // ERROR "Found IsInBounds$"
183 func useSlice(a []int) {