mirror of
https://github.com/golang/go
synced 2024-10-05 16:41:21 -06:00
[dev.ssa] cmd/compile: used Bounded field to fix empty range loops
for i, v := range a { } Walk converts this to a regular for loop, like this: for i := 0, p := &a[0]; i < len(a); i++, p++ { v := *p } Unfortunately, &a[0] fails its bounds check when a is the empty slice (or string). The old compiler gets around this by marking &a[0] as Bounded, meaning "don't emit bounds checks for this index op". This change makes SSA honor that same mark. The SSA compiler hasn't implemented bounds check panics yet, so the failed bounds check just causes the current routine to return immediately. Fixes bytes package tests. Change-Id: Ibe838853ef4046c92f76adbded8cca3b1e449e0b Reviewed-on: https://go-review.googlesource.com/13685 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
parent
67cbd5b51d
commit
46e62f873a
@ -1313,7 +1313,9 @@ func (s *state) expr(n *Node) *ssa.Value {
|
||||
len = s.constInt(Types[TINT], n.Left.Type.Bound)
|
||||
elemtype = n.Left.Type.Type
|
||||
}
|
||||
s.boundsCheck(i, len)
|
||||
if !n.Bounded {
|
||||
s.boundsCheck(i, len)
|
||||
}
|
||||
return s.newValue2(ssa.OpArrayIndex, elemtype, a, i)
|
||||
} else { // slice
|
||||
p := s.addr(n)
|
||||
@ -1530,7 +1532,9 @@ func (s *state) addr(n *Node) *ssa.Value {
|
||||
i := s.expr(n.Right)
|
||||
i = s.extendIndex(i)
|
||||
len := s.newValue1(ssa.OpSliceLen, Types[TUINTPTR], a)
|
||||
s.boundsCheck(i, len)
|
||||
if !n.Bounded {
|
||||
s.boundsCheck(i, len)
|
||||
}
|
||||
p := s.newValue1(ssa.OpSlicePtr, Ptrto(n.Left.Type.Type), a)
|
||||
return s.newValue2(ssa.OpPtrIndex, Ptrto(n.Left.Type.Type), p, i)
|
||||
} else { // array
|
||||
@ -1538,7 +1542,9 @@ func (s *state) addr(n *Node) *ssa.Value {
|
||||
i := s.expr(n.Right)
|
||||
i = s.extendIndex(i)
|
||||
len := s.constInt(Types[TINT], n.Left.Type.Bound)
|
||||
s.boundsCheck(i, len)
|
||||
if !n.Bounded {
|
||||
s.boundsCheck(i, len)
|
||||
}
|
||||
return s.newValue2(ssa.OpPtrIndex, Ptrto(n.Left.Type.Type), a, i)
|
||||
}
|
||||
case OIND:
|
||||
|
15
src/cmd/compile/internal/gc/testdata/ctl_ssa.go
vendored
15
src/cmd/compile/internal/gc/testdata/ctl_ssa.go
vendored
@ -43,10 +43,25 @@ func testPhiControl() {
|
||||
}
|
||||
}
|
||||
|
||||
func emptyRange_ssa(b []byte) bool {
|
||||
for _, x := range b {
|
||||
_ = x
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func testEmptyRange() {
|
||||
if !emptyRange_ssa([]byte{}) {
|
||||
println("emptyRange_ssa([]byte{})=false, want true")
|
||||
failed = true
|
||||
}
|
||||
}
|
||||
|
||||
var failed = false
|
||||
|
||||
func main() {
|
||||
testPhiControl()
|
||||
testEmptyRange()
|
||||
if failed {
|
||||
panic("failed")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user