$ cat f.go
package p
func f(s string) {
if len(s) >= 2 {
s = s[1:]
_ = s[0]
}
}
$ go version
go version devel +6d5caf38e3 Thu Nov 22 02:59:55 2018 +0000 linux/amd64
$ go build -gcflags=-d=ssa/check_bce/debug=1 f.go
# command-line-arguments
./f.go:6:8: Found IsInBounds
The bounds check disappears as soon as we rewrite the code to not reslice s. This shows up in real code fairly often, for example, I encountered it in a somewhat hot function in the encoding/json decoder:
if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
s = s[1:]
if s[0] == '+' || s[0] == '-' { // bounds check isn't eliminated here
I'm not sure how easy it would be to make the prove pass aware of slice expressions. I think handling the simple x = x[N:] case (where N is constant) should be doable, and hopefully remove a few dozen bounds checks across the standard library.
/cc @aclements @rasky @josharian
The bounds check disappears as soon as we rewrite the code to not reslice
s. This shows up in real code fairly often, for example, I encountered it in a somewhat hot function in theencoding/jsondecoder:I'm not sure how easy it would be to make the prove pass aware of slice expressions. I think handling the simple
x = x[N:]case (whereNis constant) should be doable, and hopefully remove a few dozen bounds checks across the standard library./cc @aclements @rasky @josharian