modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/checkbce.go (about) 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 }