modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/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 // We optimize comparisons with small constant strings (see cmd/compile/internal/gc/walk.go), 254 // so this string literal must be long. 255 if a[:n>>1] == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" { 256 return 0 257 } 258 return 1 259 } 260 261 func f11a(a []int, i int) { 262 useInt(a[i]) 263 useInt(a[i]) // ERROR "Proved boolean IsInBounds$" 264 } 265 266 func f11b(a []int, i int) { 267 useSlice(a[i:]) 268 useSlice(a[i:]) // ERROR "Proved boolean IsSliceInBounds$" 269 } 270 271 func f11c(a []int, i int) { 272 useSlice(a[:i]) 273 useSlice(a[:i]) // ERROR "Proved boolean IsSliceInBounds$" 274 } 275 276 func f11d(a []int, i int) { 277 useInt(a[2*i+7]) 278 useInt(a[2*i+7]) // ERROR "Proved boolean IsInBounds$" 279 } 280 281 func f12(a []int, b int) { 282 useSlice(a[:b]) 283 } 284 285 func f13a(a, b, c int, x bool) int { 286 if a > 12 { 287 if x { 288 if a < 12 { // ERROR "Disproved Less64$" 289 return 1 290 } 291 } 292 if x { 293 if a <= 12 { // ERROR "Disproved Leq64$" 294 return 2 295 } 296 } 297 if x { 298 if a == 12 { // ERROR "Disproved Eq64$" 299 return 3 300 } 301 } 302 if x { 303 if a >= 12 { // ERROR "Proved Geq64$" 304 return 4 305 } 306 } 307 if x { 308 if a > 12 { // ERROR "Proved boolean Greater64$" 309 return 5 310 } 311 } 312 return 6 313 } 314 return 0 315 } 316 317 func f13b(a int, x bool) int { 318 if a == -9 { 319 if x { 320 if a < -9 { // ERROR "Disproved Less64$" 321 return 7 322 } 323 } 324 if x { 325 if a <= -9 { // ERROR "Proved Leq64$" 326 return 8 327 } 328 } 329 if x { 330 if a == -9 { // ERROR "Proved boolean Eq64$" 331 return 9 332 } 333 } 334 if x { 335 if a >= -9 { // ERROR "Proved Geq64$" 336 return 10 337 } 338 } 339 if x { 340 if a > -9 { // ERROR "Disproved Greater64$" 341 return 11 342 } 343 } 344 return 12 345 } 346 return 0 347 } 348 349 func f13c(a int, x bool) int { 350 if a < 90 { 351 if x { 352 if a < 90 { // ERROR "Proved boolean Less64$" 353 return 13 354 } 355 } 356 if x { 357 if a <= 90 { // ERROR "Proved Leq64$" 358 return 14 359 } 360 } 361 if x { 362 if a == 90 { // ERROR "Disproved Eq64$" 363 return 15 364 } 365 } 366 if x { 367 if a >= 90 { // ERROR "Disproved Geq64$" 368 return 16 369 } 370 } 371 if x { 372 if a > 90 { // ERROR "Disproved Greater64$" 373 return 17 374 } 375 } 376 return 18 377 } 378 return 0 379 } 380 381 func f13d(a int) int { 382 if a < 5 { 383 if a < 9 { // ERROR "Proved Less64$" 384 return 1 385 } 386 } 387 return 0 388 } 389 390 func f13e(a int) int { 391 if a > 9 { 392 if a > 5 { // ERROR "Proved Greater64$" 393 return 1 394 } 395 } 396 return 0 397 } 398 399 func f13f(a int64) int64 { 400 if a > math.MaxInt64 { 401 // Unreachable, but prove doesn't know that. 402 if a == 0 { 403 return 1 404 } 405 } 406 return 0 407 } 408 409 func f13g(a int) int { 410 if a < 3 { 411 return 5 412 } 413 if a > 3 { 414 return 6 415 } 416 if a == 3 { // ERROR "Proved Eq64$" 417 return 7 418 } 419 return 8 420 } 421 422 func f13h(a int) int { 423 if a < 3 { 424 if a > 1 { 425 if a == 2 { // ERROR "Proved Eq64$" 426 return 5 427 } 428 } 429 } 430 return 0 431 } 432 433 func f13i(a uint) int { 434 if a == 0 { 435 return 1 436 } 437 if a > 0 { // ERROR "Proved Greater64U$" 438 return 2 439 } 440 return 3 441 } 442 443 func f14(p, q *int, a []int) { 444 // This crazy ordering usually gives i1 the lowest value ID, 445 // j the middle value ID, and i2 the highest value ID. 446 // That used to confuse CSE because it ordered the args 447 // of the two + ops below differently. 448 // That in turn foiled bounds check elimination. 449 i1 := *p 450 j := *q 451 i2 := *p 452 useInt(a[i1+j]) 453 useInt(a[i2+j]) // ERROR "Proved boolean IsInBounds$" 454 } 455 456 func f15(s []int, x int) { 457 useSlice(s[x:]) 458 useSlice(s[:x]) // ERROR "Proved IsSliceInBounds$" 459 } 460 461 func f16(s []int) []int { 462 if len(s) >= 10 { 463 return s[:10] // ERROR "Proved non-negative bounds IsSliceInBounds$" 464 } 465 return nil 466 } 467 468 //go:noinline 469 func useInt(a int) { 470 } 471 472 //go:noinline 473 func useSlice(a []int) { 474 } 475 476 func main() { 477 }