1 // errorcheck -0 -d=ssa/check_bce/debug=3
3 //go:build amd64 && !gcflags_noopt
5 // Copyright 2016 The Go Authors. All rights reserved.
6 // Use of this source code is governed by a BSD-style
7 // license that can be found in the LICENSE file.
9 // Test that the compiler does bounds check elimination as expected.
10 // This avoids accidental regressions.
14 import "encoding/binary"
17 a[0] = 1 // ERROR "Found IsInBounds$"
19 a[6] = 1 // ERROR "Found IsInBounds$"
25 func f1(a [256]int, i int) {
27 useInt(a[i]) // ERROR "Found IsInBounds$"
29 useInt(a[j]) // ERROR "Found IsInBounds$"
35 if 4 <= i && i < len(a) {
42 func f2(a [256]int, i uint) {
43 useInt(a[i]) // ERROR "Found IsInBounds$"
52 func f2a(a [35]int, i uint8) {
53 useInt(a[i]) // ERROR "Found IsInBounds$"
60 func f2b(a [35]int, i uint16) {
61 useInt(a[i]) // ERROR "Found IsInBounds$"
68 func f2c(a [35]int, i uint32) {
69 useInt(a[i]) // ERROR "Found IsInBounds$"
76 func f3(a [256]int, i uint8) {
82 func f4(a [27]int, i uint8) {
96 func f6(a [32]int, b [64]int, i int) {
97 useInt(a[uint32(i*0x07C4ACDD)>>27])
98 useInt(b[uint64(i*0x07C4ACDD)>>58])
99 useInt(a[uint(i*0x07C4ACDD)>>59])
101 // The following bounds should not be removed because they can overflow.
102 useInt(a[uint32(i*0x106297f105d0cc86)>>26]) // ERROR "Found IsInBounds$"
103 useInt(b[uint64(i*0x106297f105d0cc86)>>57]) // ERROR "Found IsInBounds$"
104 useInt(a[int32(i*0x106297f105d0cc86)>>26]) // ERROR "Found IsInBounds$"
105 useInt(b[int64(i*0x106297f105d0cc86)>>57]) // ERROR "Found IsInBounds$"
117 useInt(a[3]) // ERROR "Found IsInBounds$"
124 for i := range a[:256] { // ERROR "Found IsSliceInBounds$"
125 useInt(a[i]) // ERROR "Found IsInBounds$"
133 func g4(a [100]int) {
134 for i := 10; i < 50; i++ {
140 // The following are out of bounds.
141 if a[0] == 0xdeadbeef {
142 // This is a trick to prohibit sccp to optimize out the following out of bound check
145 useInt(a[i-11]) // ERROR "Found IsInBounds$"
146 useInt(a[i+51]) // ERROR "Found IsInBounds$"
150 func decode1(data []byte) (x uint64) {
151 for len(data) >= 32 {
152 x += binary.BigEndian.Uint64(data[:8])
153 x += binary.BigEndian.Uint64(data[8:16])
154 x += binary.BigEndian.Uint64(data[16:24])
155 x += binary.BigEndian.Uint64(data[24:32])
161 func decode2(data []byte) (x uint64) {
162 // TODO(rasky): this should behave like decode1 and compile to no
163 // boundchecks. We're currently not able to remove all of them.
164 for len(data) >= 32 {
165 x += binary.BigEndian.Uint64(data)
167 x += binary.BigEndian.Uint64(data) // ERROR "Found IsInBounds$"
169 x += binary.BigEndian.Uint64(data) // ERROR "Found IsInBounds$"
171 x += binary.BigEndian.Uint64(data) // ERROR "Found IsInBounds$"
182 func useSlice(a []int) {