Closed
Description
See #31586 (comment)
Core problem can be reduced to:
package scratch
import "encoding/binary"
func A1(b []byte) {
key64 := uint64(1024)
for len(b) >= 32 {
v := binary.LittleEndian.Uint64(b)
binary.LittleEndian.PutUint64(b, v^key64)
v = binary.LittleEndian.Uint64(b[8:])
binary.LittleEndian.PutUint64(b[8:], v^key64)
v = binary.LittleEndian.Uint64(b[16:])
binary.LittleEndian.PutUint64(b[16:], v^key64)
v = binary.LittleEndian.Uint64(b[24:])
binary.LittleEndian.PutUint64(b[24:], v^key64)
b = b[32:]
}
}
func A2(b []byte) {
key64 := uint64(1024)
for len(b) >= 32 {
v := binary.LittleEndian.Uint64(b)
binary.LittleEndian.PutUint64(b, v^key64)
v = binary.LittleEndian.Uint64(b[8:16])
binary.LittleEndian.PutUint64(b[8:16], v^key64)
v = binary.LittleEndian.Uint64(b[16:24])
binary.LittleEndian.PutUint64(b[16:24], v^key64)
v = binary.LittleEndian.Uint64(b[24:32])
binary.LittleEndian.PutUint64(b[24:32], v^key64)
b = b[32:]
}
}
BCE:
$ go build -gcflags="-d=ssa/check_bce/debug=1" scratch.go
# command-line-arguments
./scratch.go:10:34: Found IsInBounds
./scratch.go:12:34: Found IsInBounds
./scratch.go:14:34: Found IsInBounds
Bound checks remain in A1 even though they are not needed but are eliminated in A2 due to the explicit and not unbounded slices.
It was the _ = b[7] line in PutUint64() that was cause the bounds checks. The compiler failed to prove it's not needed with PutUint64(b[8:], x) however it does eliminate the first check in PutUint64(b, x).
I'm on 1.13.4 on macOS.
Metadata
Metadata
Assignees
Labels
Type
Projects
Relationships
Development
No branches or pull requests
Activity
josharian commentedon Nov 9, 2019
cc @zdjones
[-]cmd/go: improve BCE to detect safe unbounded slicing[/-][+]cmd/compile: improve BCE to detect safe unbounded slicing[/+]zdjones commentedon Nov 11, 2019
This is a duplicate of #24876. Also see #19126
The issue is that the prove pass does not currently do any arithimetic when assesing
b[16:]
and therefore has no information about the length of the resulting slice. see this comment: #19126 (comment).I have a chain of CLs that fix this, but they are not complete this cycle.
zdjones commentedon Nov 11, 2019
Here is the CL chain that fixes this issue: https://go-review.googlesource.com/c/go/+/190657
agnivade commentedon Nov 11, 2019
Closing as a duplicate.