Open
Description
This is follow-up to #19714 where prove/BCE were taught to take transitivity into account, but originally-motivating example where indices are constructed as arithmetic expressions remains with bounds checks not eliminated:
package hex
func Encode(dst, src []byte) {
if len(dst) < len(src) * 2 {
panic("dst overflow")
}
for i, _ := range src {
dst[i*2] = 0 // XXX BC not eliminated
dst[i*2+1] = 0 // XXX BC not eliminated
}
}
$ gotip version
go version devel +030ac2c719 Tue May 1 05:02:43 2018 +0000 linux/amd64
$ gotip tool compile -S 3.go |go2asm
TEXT ·Encode(SB), $24-48 // 3.go:3
// MOVQ (TLS), CX (stack growth prologue)
// CMPQ SP, 16(CX)
// JLS 158
// SUBQ $24, SP
// MOVQ BP, 16(SP) (BP save)
// LEAQ 16(SP), BP (BP init)
// FUNCDATA $0, gclocals·7578f313ff9d15b1ec5bd5c7e7ab3d8c(SB) (args)
FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB) (locals)
MOVQ src+32(FP), AX // 3.go:4
MOVQ AX, CX
SHLQ $1, AX
MOVQ dst+8(FP), DX
CMPQ DX, AX
JLT pc128
MOVQ dst+0(FP), AX
XORL BX, BX
JMP pc72 // 3.go:8
pc63:
MOVB $0, 1(BX)(AX*1) // 3.go:10
LEAQ 1(SI), BX // 3.go:8
pc72:
CMPQ BX, CX
JGE pc104
MOVQ BX, SI
SHLQ $1, BX // 3.go:9
CMPQ BX, DX
JCC pc121 // <-- NOTE
MOVB $0, (AX)(BX*1)
LEAQ 1(SI)(SI*1), DI // 3.go:10
CMPQ DI, DX
JCS pc63
JMP pc114 // <-- NOTE
pc114:
// PCDATA $0, $1 (stack growth)
// CALL runtime.panicindex(SB) // <-- NOTE
// UNDEF
pc121:
// PCDATA $0, $1 // 3.go:9
// CALL runtime.panicindex(SB) // <-- NOTE
// UNDEF
pc128:
// LEAQ type.string(SB), AX // 3.go:5
// MOVQ AX, (SP)
// LEAQ ·statictmp_0(SB), AX
// MOVQ AX, 8(SP)
// PCDATA $0, $1
// CALL runtime.gopanic(SB)
// UNDEF
// NOP
// PCDATA $0, $-1 // 3.go:3
// CALL runtime.morestack_noctxt(SB)
// JMP 0
/cc @rasky, @josharian