]> Cypherpunks.ru repositories - gostls13.git/blob - test/checkbce.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / checkbce.go
1 // errorcheck -0 -d=ssa/check_bce/debug=3
2
3 //go:build amd64 && !gcflags_noopt
4
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.
8
9 // Test that the compiler does bounds check elimination as expected.
10 // This avoids accidental regressions.
11
12 package main
13
14 import "encoding/binary"
15
16 func f0(a []int) {
17         a[0] = 1 // ERROR "Found IsInBounds$"
18         a[0] = 1
19         a[6] = 1 // ERROR "Found IsInBounds$"
20         a[6] = 1
21         a[5] = 1
22         a[5] = 1
23 }
24
25 func f1(a [256]int, i int) {
26         var j int
27         useInt(a[i]) // ERROR "Found IsInBounds$"
28         j = i % 256
29         useInt(a[j]) // ERROR "Found IsInBounds$"
30         j = i & 255
31         useInt(a[j])
32         j = i & 17
33         useInt(a[j])
34
35         if 4 <= i && i < len(a) {
36                 useInt(a[i])
37                 useInt(a[i-1])
38                 useInt(a[i-4])
39         }
40 }
41
42 func f2(a [256]int, i uint) {
43         useInt(a[i]) // ERROR "Found IsInBounds$"
44         j := i % 256
45         useInt(a[j])
46         j = i & 255
47         useInt(a[j])
48         j = i & 17
49         useInt(a[j])
50 }
51
52 func f2a(a [35]int, i uint8) {
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 f2b(a [35]int, i uint16) {
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 f2c(a [35]int, i uint32) {
69         useInt(a[i]) // ERROR "Found IsInBounds$"
70         j := i & 34
71         useInt(a[j])
72         j = i & 17
73         useInt(a[j])
74 }
75
76 func f3(a [256]int, i uint8) {
77         useInt(a[i])
78         useInt(a[i+10])
79         useInt(a[i+14])
80 }
81
82 func f4(a [27]int, i uint8) {
83         useInt(a[i%15])
84         useInt(a[i%19])
85         useInt(a[i%27])
86 }
87
88 func f5(a []int) {
89         if len(a) > 5 {
90                 useInt(a[5])
91                 useSlice(a[6:])
92                 useSlice(a[:6])
93         }
94 }
95
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])
100
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$"
106 }
107
108 func g1(a []int) {
109         for i := range a {
110                 a[i] = i
111                 useSlice(a[:i+1])
112                 useSlice(a[:i])
113         }
114 }
115
116 func g2(a []int) {
117         useInt(a[3]) // ERROR "Found IsInBounds$"
118         useInt(a[2])
119         useInt(a[1])
120         useInt(a[0])
121 }
122
123 func g3(a []int) {
124         for i := range a[:256] { // ERROR "Found IsSliceInBounds$"
125                 useInt(a[i]) // ERROR "Found IsInBounds$"
126         }
127         b := a[:256]
128         for i := range b {
129                 useInt(b[i])
130         }
131 }
132
133 func g4(a [100]int) {
134         for i := 10; i < 50; i++ {
135                 useInt(a[i-10])
136                 useInt(a[i])
137                 useInt(a[i+25])
138                 useInt(a[i+50])
139
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
143                         continue
144                 }
145                 useInt(a[i-11]) // ERROR "Found IsInBounds$"
146                 useInt(a[i+51]) // ERROR "Found IsInBounds$"
147         }
148 }
149
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])
156                 data = data[32:]
157         }
158         return x
159 }
160
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)
166                 data = data[8:]
167                 x += binary.BigEndian.Uint64(data) // ERROR "Found IsInBounds$"
168                 data = data[8:]
169                 x += binary.BigEndian.Uint64(data) // ERROR "Found IsInBounds$"
170                 data = data[8:]
171                 x += binary.BigEndian.Uint64(data) // ERROR "Found IsInBounds$"
172                 data = data[8:]
173         }
174         return x
175 }
176
177 //go:noinline
178 func useInt(a int) {
179 }
180
181 //go:noinline
182 func useSlice(a []int) {
183 }
184
185 func main() {
186 }