Home | History | Annotate | Download | only in test
      1 // +build amd64
      2 // errorcheck -0 -d=ssa/check_bce/debug=3
      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.
      7 
      8 // Test that the compiler does bounds check elimination as expected.
      9 // This avoids accidental regressions.
     10 
     11 package main
     12 
     13 func f0(a []int) {
     14 	a[0] = 1 // ERROR "Found IsInBounds$"
     15 	a[0] = 1
     16 	a[6] = 1 // ERROR "Found IsInBounds$"
     17 	a[6] = 1
     18 	a[5] = 1
     19 	a[5] = 1
     20 }
     21 
     22 func f1(a [256]int, i int) {
     23 	var j int
     24 	useInt(a[i]) // ERROR "Found IsInBounds$"
     25 	j = i % 256
     26 	useInt(a[j]) // ERROR "Found IsInBounds$"
     27 	j = i & 255
     28 	useInt(a[j])
     29 	j = i & 17
     30 	useInt(a[j])
     31 
     32 	if 4 <= i && i < len(a) {
     33 		useInt(a[i])
     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.
     37 		useInt(a[i-4])
     38 	}
     39 }
     40 
     41 func f2(a [256]int, i uint) {
     42 	useInt(a[i]) // ERROR "Found IsInBounds$"
     43 	j := i % 256
     44 	useInt(a[j])
     45 	j = i & 255
     46 	useInt(a[j])
     47 	j = i & 17
     48 	useInt(a[j])
     49 }
     50 
     51 func f2a(a [35]int, i uint8) {
     52 	useInt(a[i]) // ERROR "Found IsInBounds$"
     53 	j := i & 34
     54 	useInt(a[j])
     55 	j = i & 17
     56 	useInt(a[j])
     57 }
     58 
     59 func f2b(a [35]int, i uint16) {
     60 	useInt(a[i]) // ERROR "Found IsInBounds$"
     61 	j := i & 34
     62 	useInt(a[j])
     63 	j = i & 17
     64 	useInt(a[j])
     65 }
     66 
     67 func f2c(a [35]int, i uint32) {
     68 	useInt(a[i]) // ERROR "Found IsInBounds$"
     69 	j := i & 34
     70 	useInt(a[j])
     71 	j = i & 17
     72 	useInt(a[j])
     73 }
     74 
     75 func f3(a [256]int, i uint8) {
     76 	useInt(a[i])
     77 	useInt(a[i+10])
     78 	useInt(a[i+14])
     79 }
     80 
     81 func f4(a [27]int, i uint8) {
     82 	useInt(a[i%15])
     83 	useInt(a[i%19])
     84 	useInt(a[i%27])
     85 }
     86 
     87 func f5(a []int) {
     88 	if len(a) > 5 {
     89 		useInt(a[5])
     90 		useSlice(a[6:])
     91 		useSlice(a[:6])
     92 	}
     93 }
     94 
     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])
     99 
    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$"
    105 }
    106 
    107 func g1(a []int) {
    108 	for i := range a {
    109 		a[i] = i
    110 		useSlice(a[:i+1])
    111 		useSlice(a[:i])
    112 	}
    113 }
    114 
    115 func g2(a []int) {
    116 	useInt(a[3]) // ERROR "Found IsInBounds$"
    117 	useInt(a[2])
    118 	useInt(a[1])
    119 	useInt(a[0])
    120 }
    121 
    122 func g3(a []int) {
    123 	for i := range a[:256] { // ERROR "Found IsSliceInBounds$"
    124 		useInt(a[i]) // ERROR "Found IsInBounds$"
    125 	}
    126 	b := a[:256]
    127 	for i := range b {
    128 		useInt(b[i])
    129 	}
    130 }
    131 
    132 func g4(a [100]int) {
    133 	for i := 10; i < 50; i++ {
    134 		useInt(a[i-10])
    135 		useInt(a[i])
    136 		useInt(a[i+25])
    137 		useInt(a[i+50])
    138 
    139 		// The following are out of bounds.
    140 		useInt(a[i-11]) // ERROR "Found IsInBounds$"
    141 		useInt(a[i+51]) // ERROR "Found IsInBounds$"
    142 	}
    143 }
    144 
    145 //go:noinline
    146 func useInt(a int) {
    147 }
    148 
    149 //go:noinline
    150 func useSlice(a []int) {
    151 }
    152 
    153 func main() {
    154 }
    155