github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/test/prove.go (about) 1 // +build amd64 2 // errorcheck -0 -d=ssa/prove/debug=1 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 package main 9 10 import "math" 11 12 func f0(a []int) int { 13 a[0] = 1 14 a[0] = 1 // ERROR "Proved boolean IsInBounds$" 15 a[6] = 1 16 a[6] = 1 // ERROR "Proved boolean IsInBounds$" 17 a[5] = 1 // ERROR "Proved IsInBounds$" 18 a[5] = 1 // ERROR "Proved boolean IsInBounds$" 19 return 13 20 } 21 22 func f1(a []int) int { 23 if len(a) <= 5 { 24 return 18 25 } 26 a[0] = 1 // ERROR "Proved non-negative bounds IsInBounds$" 27 a[0] = 1 // ERROR "Proved boolean IsInBounds$" 28 a[6] = 1 29 a[6] = 1 // ERROR "Proved boolean IsInBounds$" 30 a[5] = 1 // ERROR "Proved IsInBounds$" 31 a[5] = 1 // ERROR "Proved boolean IsInBounds$" 32 return 26 33 } 34 35 func f1b(a []int, i int, j uint) int { 36 if i >= 0 && i < len(a) { 37 return a[i] // ERROR "Proved non-negative bounds IsInBounds$" 38 } 39 if i >= 10 && i < len(a) { 40 return a[i] // ERROR "Proved non-negative bounds IsInBounds$" 41 } 42 if i >= 10 && i < len(a) { 43 return a[i] // ERROR "Proved non-negative bounds IsInBounds$" 44 } 45 if i >= 10 && i < len(a) { // todo: handle this case 46 return a[i-10] 47 } 48 if j < uint(len(a)) { 49 return a[j] // ERROR "Proved IsInBounds$" 50 } 51 return 0 52 } 53 54 func f1c(a []int, i int64) int { 55 c := uint64(math.MaxInt64 + 10) // overflows int 56 d := int64(c) 57 if i >= d && i < int64(len(a)) { 58 // d overflows, should not be handled. 59 return a[i] 60 } 61 return 0 62 } 63 64 func f2(a []int) int { 65 for i := range a { 66 a[i+1] = i 67 a[i+1] = i // ERROR "Proved boolean IsInBounds$" 68 } 69 return 34 70 } 71 72 func f3(a []uint) int { 73 for i := uint(0); i < uint(len(a)); i++ { 74 a[i] = i // ERROR "Proved IsInBounds$" 75 } 76 return 41 77 } 78 79 func f4a(a, b, c int) int { 80 if a < b { 81 if a == b { // ERROR "Disproved Eq64$" 82 return 47 83 } 84 if a > b { // ERROR "Disproved Greater64$" 85 return 50 86 } 87 if a < b { // ERROR "Proved boolean Less64$" 88 return 53 89 } 90 if a == b { // ERROR "Disproved boolean Eq64$" 91 return 56 92 } 93 if a > b { // ERROR "Disproved boolean Greater64$" 94 return 59 95 } 96 return 61 97 } 98 return 63 99 } 100 101 func f4b(a, b, c int) int { 102 if a <= b { 103 if a >= b { 104 if a == b { // ERROR "Proved Eq64$" 105 return 70 106 } 107 return 75 108 } 109 return 77 110 } 111 return 79 112 } 113 114 func f4c(a, b, c int) int { 115 if a <= b { 116 if a >= b { 117 if a != b { // ERROR "Disproved Neq64$" 118 return 73 119 } 120 return 75 121 } 122 return 77 123 } 124 return 79 125 } 126 127 func f4d(a, b, c int) int { 128 if a < b { 129 if a < c { 130 if a < b { // ERROR "Proved boolean Less64$" 131 if a < c { // ERROR "Proved boolean Less64$" 132 return 87 133 } 134 return 89 135 } 136 return 91 137 } 138 return 93 139 } 140 return 95 141 } 142 143 func f4e(a, b, c int) int { 144 if a < b { 145 if b > a { // ERROR "Proved Greater64$" 146 return 101 147 } 148 return 103 149 } 150 return 105 151 } 152 153 func f4f(a, b, c int) int { 154 if a <= b { 155 if b > a { 156 if b == a { // ERROR "Disproved Eq64$" 157 return 112 158 } 159 return 114 160 } 161 if b >= a { // ERROR "Proved Geq64$" 162 if b == a { // ERROR "Proved Eq64$" 163 return 118 164 } 165 return 120 166 } 167 return 122 168 } 169 return 124 170 } 171 172 func f5(a, b uint) int { 173 if a == b { 174 if a <= b { // ERROR "Proved Leq64U$" 175 return 130 176 } 177 return 132 178 } 179 return 134 180 } 181 182 // These comparisons are compile time constants. 183 func f6a(a uint8) int { 184 if a < a { // ERROR "Disproved Less8U$" 185 return 140 186 } 187 return 151 188 } 189 190 func f6b(a uint8) int { 191 if a < a { // ERROR "Disproved Less8U$" 192 return 140 193 } 194 return 151 195 } 196 197 func f6x(a uint8) int { 198 if a > a { // ERROR "Disproved Greater8U$" 199 return 143 200 } 201 return 151 202 } 203 204 func f6d(a uint8) int { 205 if a <= a { // ERROR "Proved Leq8U$" 206 return 146 207 } 208 return 151 209 } 210 211 func f6e(a uint8) int { 212 if a >= a { // ERROR "Proved Geq8U$" 213 return 149 214 } 215 return 151 216 } 217 218 func f7(a []int, b int) int { 219 if b < len(a) { 220 a[b] = 3 221 if b < len(a) { // ERROR "Proved boolean Less64$" 222 a[b] = 5 // ERROR "Proved boolean IsInBounds$" 223 } 224 } 225 return 161 226 } 227 228 func f8(a, b uint) int { 229 if a == b { 230 return 166 231 } 232 if a > b { 233 return 169 234 } 235 if a < b { // ERROR "Proved Less64U$" 236 return 172 237 } 238 return 174 239 } 240 241 func f9(a, b bool) int { 242 if a { 243 return 1 244 } 245 if a || b { // ERROR "Disproved boolean Arg$" 246 return 2 247 } 248 return 3 249 } 250 251 func f10(a string) int { 252 n := len(a) 253 if a[:n>>1] == "aaaaaaaaaaaaaa" { 254 return 0 255 } 256 return 1 257 } 258 259 func f11a(a []int, i int) { 260 useInt(a[i]) 261 useInt(a[i]) // ERROR "Proved boolean IsInBounds$" 262 } 263 264 func f11b(a []int, i int) { 265 useSlice(a[i:]) 266 useSlice(a[i:]) // ERROR "Proved boolean IsSliceInBounds$" 267 } 268 269 func f11c(a []int, i int) { 270 useSlice(a[:i]) 271 useSlice(a[:i]) // ERROR "Proved boolean IsSliceInBounds$" 272 } 273 274 func f11d(a []int, i int) { 275 useInt(a[2*i+7]) 276 useInt(a[2*i+7]) // ERROR "Proved boolean IsInBounds$" 277 } 278 279 func f12(a []int, b int) { 280 useSlice(a[:b]) 281 } 282 283 func f13a(a, b, c int, x bool) int { 284 if a > 12 { 285 if x { 286 if a < 12 { // ERROR "Disproved Less64$" 287 return 1 288 } 289 } 290 if x { 291 if a <= 12 { // ERROR "Disproved Leq64$" 292 return 2 293 } 294 } 295 if x { 296 if a == 12 { // ERROR "Disproved Eq64$" 297 return 3 298 } 299 } 300 if x { 301 if a >= 12 { // ERROR "Proved Geq64$" 302 return 4 303 } 304 } 305 if x { 306 if a > 12 { // ERROR "Proved boolean Greater64$" 307 return 5 308 } 309 } 310 return 6 311 } 312 return 0 313 } 314 315 func f13b(a int, x bool) int { 316 if a == -9 { 317 if x { 318 if a < -9 { // ERROR "Disproved Less64$" 319 return 7 320 } 321 } 322 if x { 323 if a <= -9 { // ERROR "Proved Leq64$" 324 return 8 325 } 326 } 327 if x { 328 if a == -9 { // ERROR "Proved boolean Eq64$" 329 return 9 330 } 331 } 332 if x { 333 if a >= -9 { // ERROR "Proved Geq64$" 334 return 10 335 } 336 } 337 if x { 338 if a > -9 { // ERROR "Disproved Greater64$" 339 return 11 340 } 341 } 342 return 12 343 } 344 return 0 345 } 346 347 func f13c(a int, x bool) int { 348 if a < 90 { 349 if x { 350 if a < 90 { // ERROR "Proved boolean Less64$" 351 return 13 352 } 353 } 354 if x { 355 if a <= 90 { // ERROR "Proved Leq64$" 356 return 14 357 } 358 } 359 if x { 360 if a == 90 { // ERROR "Disproved Eq64$" 361 return 15 362 } 363 } 364 if x { 365 if a >= 90 { // ERROR "Disproved Geq64$" 366 return 16 367 } 368 } 369 if x { 370 if a > 90 { // ERROR "Disproved Greater64$" 371 return 17 372 } 373 } 374 return 18 375 } 376 return 0 377 } 378 379 func f13d(a int) int { 380 if a < 5 { 381 if a < 9 { // ERROR "Proved Less64$" 382 return 1 383 } 384 } 385 return 0 386 } 387 388 func f13e(a int) int { 389 if a > 9 { 390 if a > 5 { // ERROR "Proved Greater64$" 391 return 1 392 } 393 } 394 return 0 395 } 396 397 func f13f(a int64) int64 { 398 if a > math.MaxInt64 { 399 // Unreachable, but prove doesn't know that. 400 if a == 0 { 401 return 1 402 } 403 } 404 return 0 405 } 406 407 func f13g(a int) int { 408 if a < 3 { 409 return 5 410 } 411 if a > 3 { 412 return 6 413 } 414 if a == 3 { // ERROR "Proved Eq64$" 415 return 7 416 } 417 return 8 418 } 419 420 func f13h(a int) int { 421 if a < 3 { 422 if a > 1 { 423 if a == 2 { // ERROR "Proved Eq64$" 424 return 5 425 } 426 } 427 } 428 return 0 429 } 430 431 func f13i(a uint) int { 432 if a == 0 { 433 return 1 434 } 435 if a > 0 { // ERROR "Proved Greater64U$" 436 return 2 437 } 438 return 3 439 } 440 441 func f14(p, q *int, a []int) { 442 // This crazy ordering usually gives i1 the lowest value ID, 443 // j the middle value ID, and i2 the highest value ID. 444 // That used to confuse CSE because it ordered the args 445 // of the two + ops below differently. 446 // That in turn foiled bounds check elimination. 447 i1 := *p 448 j := *q 449 i2 := *p 450 useInt(a[i1+j]) 451 useInt(a[i2+j]) // ERROR "Proved boolean IsInBounds$" 452 } 453 454 func f15(s []int, x int) { 455 useSlice(s[x:]) 456 useSlice(s[:x]) // ERROR "Proved IsSliceInBounds$" 457 } 458 459 func f16(s []int) []int { 460 if len(s) >= 10 { 461 return s[:10] // ERROR "Proved non-negative bounds IsSliceInBounds$" 462 } 463 return nil 464 } 465 466 //go:noinline 467 func useInt(a int) { 468 } 469 470 //go:noinline 471 func useSlice(a []int) { 472 } 473 474 func main() { 475 }