github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/test/checkbce.go (about) 1 // +build amd64 2 // errorcheck -0 -d=ssa/check_bce/debug=3 3 4 package main 5 6 func f0(a []int) { 7 a[0] = 1 // ERROR "Found IsInBounds$" 8 a[0] = 1 9 a[6] = 1 // ERROR "Found IsInBounds$" 10 a[6] = 1 11 a[5] = 1 12 a[5] = 1 13 } 14 15 func f1(a [256]int, i int) { 16 var j int 17 useInt(a[i]) // ERROR "Found IsInBounds$" 18 j = i % 256 19 useInt(a[j]) // ERROR "Found IsInBounds$" 20 j = i & 255 21 useInt(a[j]) 22 j = i & 17 23 useInt(a[j]) 24 25 if 4 <= i && i < len(a) { 26 useInt(a[i]) 27 useInt(a[i-1]) // ERROR "Found IsInBounds$" 28 // TODO: 'if 4 <= i && i < len(a)' gets rewritten to 'if uint(i - 4) < 256 - 4', 29 // which the bounds checker cannot yet use to infer that the next line doesn't need a bounds check. 30 useInt(a[i-4]) 31 } 32 } 33 34 func f2(a [256]int, i uint) { 35 useInt(a[i]) // ERROR "Found IsInBounds$" 36 j := i % 256 37 useInt(a[j]) 38 j = i & 255 39 useInt(a[j]) 40 j = i & 17 41 useInt(a[j]) 42 } 43 44 func f2a(a [35]int, i uint8) { 45 useInt(a[i]) // ERROR "Found IsInBounds$" 46 j := i & 34 47 useInt(a[j]) 48 j = i & 17 49 useInt(a[j]) 50 } 51 52 func f2b(a [35]int, i uint16) { 53 useInt(a[i]) // ERROR "Found IsInBounds$" 54 j := i & 34 55 useInt(a[j]) 56 j = i & 17 57 useInt(a[j]) 58 } 59 60 func f2c(a [35]int, i uint32) { 61 useInt(a[i]) // ERROR "Found IsInBounds$" 62 j := i & 34 63 useInt(a[j]) 64 j = i & 17 65 useInt(a[j]) 66 } 67 68 func f3(a [256]int, i uint8) { 69 useInt(a[i]) 70 useInt(a[i+10]) 71 useInt(a[i+14]) 72 } 73 74 func f4(a [27]int, i uint8) { 75 useInt(a[i%15]) 76 useInt(a[i%19]) 77 useInt(a[i%27]) 78 } 79 80 func f5(a []int) { 81 if len(a) > 5 { 82 useInt(a[5]) 83 useSlice(a[6:]) 84 useSlice(a[:6]) 85 } 86 } 87 88 func f6(a [32]int, b [64]int, i int) { 89 useInt(a[uint32(i*0x07C4ACDD)>>27]) 90 useInt(b[uint64(i*0x07C4ACDD)>>58]) 91 useInt(a[uint(i*0x07C4ACDD)>>59]) 92 93 // The following bounds should not be removed because they can overflow. 94 useInt(a[uint32(i*0x106297f105d0cc86)>>26]) // ERROR "Found IsInBounds$" 95 useInt(b[uint64(i*0x106297f105d0cc86)>>57]) // ERROR "Found IsInBounds$" 96 useInt(a[int32(i*0x106297f105d0cc86)>>26]) // ERROR "Found IsInBounds$" 97 useInt(b[int64(i*0x106297f105d0cc86)>>57]) // ERROR "Found IsInBounds$" 98 } 99 100 func g1(a []int) { 101 for i := range a { 102 a[i] = i 103 useSlice(a[:i+1]) 104 useSlice(a[:i]) 105 } 106 } 107 108 func g2(a []int) { 109 useInt(a[3]) // ERROR "Found IsInBounds$" 110 useInt(a[2]) 111 useInt(a[1]) 112 useInt(a[0]) 113 } 114 115 func g3(a []int) { 116 for i := range a[:256] { // ERROR "Found IsSliceInBounds$" 117 useInt(a[i]) // ERROR "Found IsInBounds$" 118 } 119 b := a[:256] 120 for i := range b { 121 useInt(b[i]) 122 } 123 } 124 125 func g4(a [100]int) { 126 for i := 10; i < 50; i++ { 127 useInt(a[i-10]) 128 useInt(a[i]) 129 useInt(a[i+25]) 130 useInt(a[i+50]) 131 132 // The following are out of bounds. 133 useInt(a[i-11]) // ERROR "Found IsInBounds$" 134 useInt(a[i+51]) // ERROR "Found IsInBounds$" 135 } 136 } 137 138 //go:noinline 139 func useInt(a int) { 140 } 141 142 //go:noinline 143 func useSlice(a []int) { 144 } 145 146 func main() { 147 }