1
0
mirror of https://github.com/golang/go synced 2024-11-23 20:30:04 -07:00
go/test/checkbce.go
Brad Fitzpatrick b3369063e5 test: skip some tests on noopt builder
Adds a new build tag "gcflags_noopt" that can be used in test/*.go
tests.

Fixes #27833

Change-Id: I4ea0ccd9e9e58c4639de18645fec81eb24a3a929
Reviewed-on: https://go-review.googlesource.com/136898
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2018-09-24 20:56:48 +00:00

188 lines
3.8 KiB
Go

// +build amd64,!gcflags_noopt
// errorcheck -0 -d=ssa/check_bce/debug=3
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test that the compiler does bounds check elimination as expected.
// This avoids accidental regressions.
package main
func f0(a []int) {
a[0] = 1 // ERROR "Found IsInBounds$"
a[0] = 1
a[6] = 1 // ERROR "Found IsInBounds$"
a[6] = 1
a[5] = 1
a[5] = 1
}
func f1(a [256]int, i int) {
var j int
useInt(a[i]) // ERROR "Found IsInBounds$"
j = i % 256
useInt(a[j]) // ERROR "Found IsInBounds$"
j = i & 255
useInt(a[j])
j = i & 17
useInt(a[j])
if 4 <= i && i < len(a) {
useInt(a[i])
useInt(a[i-1]) // ERROR "Found IsInBounds$"
// TODO: 'if 4 <= i && i < len(a)' gets rewritten to 'if uint(i - 4) < 256 - 4',
// which the bounds checker cannot yet use to infer that the next line doesn't need a bounds check.
useInt(a[i-4])
}
}
func f2(a [256]int, i uint) {
useInt(a[i]) // ERROR "Found IsInBounds$"
j := i % 256
useInt(a[j])
j = i & 255
useInt(a[j])
j = i & 17
useInt(a[j])
}
func f2a(a [35]int, i uint8) {
useInt(a[i]) // ERROR "Found IsInBounds$"
j := i & 34
useInt(a[j])
j = i & 17
useInt(a[j])
}
func f2b(a [35]int, i uint16) {
useInt(a[i]) // ERROR "Found IsInBounds$"
j := i & 34
useInt(a[j])
j = i & 17
useInt(a[j])
}
func f2c(a [35]int, i uint32) {
useInt(a[i]) // ERROR "Found IsInBounds$"
j := i & 34
useInt(a[j])
j = i & 17
useInt(a[j])
}
func f3(a [256]int, i uint8) {
useInt(a[i])
useInt(a[i+10])
useInt(a[i+14])
}
func f4(a [27]int, i uint8) {
useInt(a[i%15])
useInt(a[i%19])
useInt(a[i%27])
}
func f5(a []int) {
if len(a) > 5 {
useInt(a[5])
useSlice(a[6:])
useSlice(a[:6])
}
}
func f6(a [32]int, b [64]int, i int) {
useInt(a[uint32(i*0x07C4ACDD)>>27])
useInt(b[uint64(i*0x07C4ACDD)>>58])
useInt(a[uint(i*0x07C4ACDD)>>59])
// The following bounds should not be removed because they can overflow.
useInt(a[uint32(i*0x106297f105d0cc86)>>26]) // ERROR "Found IsInBounds$"
useInt(b[uint64(i*0x106297f105d0cc86)>>57]) // ERROR "Found IsInBounds$"
useInt(a[int32(i*0x106297f105d0cc86)>>26]) // ERROR "Found IsInBounds$"
useInt(b[int64(i*0x106297f105d0cc86)>>57]) // ERROR "Found IsInBounds$"
}
func g1(a []int) {
for i := range a {
a[i] = i
useSlice(a[:i+1])
useSlice(a[:i])
}
}
func g2(a []int) {
useInt(a[3]) // ERROR "Found IsInBounds$"
useInt(a[2])
useInt(a[1])
useInt(a[0])
}
func g3(a []int) {
for i := range a[:256] { // ERROR "Found IsSliceInBounds$"
useInt(a[i]) // ERROR "Found IsInBounds$"
}
b := a[:256]
for i := range b {
useInt(b[i])
}
}
func g4(a [100]int) {
for i := 10; i < 50; i++ {
useInt(a[i-10])
useInt(a[i])
useInt(a[i+25])
useInt(a[i+50])
// The following are out of bounds.
useInt(a[i-11]) // ERROR "Found IsInBounds$"
useInt(a[i+51]) // ERROR "Found IsInBounds$"
}
}
func Uint64(b []byte) uint64 {
_ = b[7] // ERROR "Found IsInBounds$"
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
}
func decode1(data []byte) (x uint64) {
for len(data) >= 32 {
x += Uint64(data[:8])
x += Uint64(data[8:16])
x += Uint64(data[16:24])
x += Uint64(data[24:32])
data = data[32:]
}
return x
}
func decode2(data []byte) (x uint64) {
// TODO(rasky): this should behave like decode1 and compile to no
// boundchecks. We're currently not able to remove all of them.
for len(data) >= 32 {
x += Uint64(data)
data = data[8:]
x += Uint64(data) // ERROR "Found IsInBounds$"
data = data[8:]
x += Uint64(data) // ERROR "Found IsInBounds$"
data = data[8:]
x += Uint64(data) // ERROR "Found IsInBounds$"
data = data[8:]
}
return x
}
//go:noinline
func useInt(a int) {
}
//go:noinline
func useSlice(a []int) {
}
func main() {
}