[moved from private email with @brtzsnr]
Consider this code, adapted from test/prove.go:
package p
func f(a []int, i int) int {
if i >= 0 && i < len(a) {
return a[i]
}
if i >= 10 && i < len(a) {
return a[i]
}
return 0
}
func g(a []int, i int) int {
if uint(i) < uint(len(a)) {
return a[i]
}
if i >= 10 && i < len(a) {
return a[i]
}
return 0
}
Functions f and g are equivalent. The only difference between them is the expression i >= 0 && i < len(a) in f vs uint(i) < uint(len(a)). And these are equivalent, because we know that len(a) is non-negative. But compiling with go tool compile -d=ssa/prove/debug=3 x.go, we get:
x.go:5: Proved non-negative bounds IsInBounds
x.go:8: Proved non-negative bounds IsInBounds
x.go:15: Proved IsInBounds
x.go:18: Disproved IsInBounds
Going from "x.go:5: Proved non-negative bounds IsInBounds" to "x.go:15: Proved IsInBounds" is a bit unfortunate, but ok. Going from "x.go:8: Proved non-negative bounds IsInBounds" to "x.go:18: Disproved IsInBounds" seems incorrect.
[moved from private email with @brtzsnr]
Consider this code, adapted from test/prove.go:
Functions f and g are equivalent. The only difference between them is the expression
i >= 0 && i < len(a)in f vsuint(i) < uint(len(a)). And these are equivalent, because we know that len(a) is non-negative. But compiling withgo tool compile -d=ssa/prove/debug=3 x.go, we get:Going from "x.go:5: Proved non-negative bounds IsInBounds" to "x.go:15: Proved IsInBounds" is a bit unfortunate, but ok. Going from "x.go:8: Proved non-negative bounds IsInBounds" to "x.go:18: Disproved IsInBounds" seems incorrect.