1
0
mirror of https://github.com/golang/go synced 2024-10-05 16:41:21 -06:00

[dev.ssa] cmd/compile/internal/ssa: fix string index

Change-Id: I984d3e0410ac38c4e42ae8e3670ea47e2140de76
Reviewed-on: https://go-review.googlesource.com/14466
Reviewed-by: Alexandru Moșoi <alexandru@mosoi.ro>
Reviewed-by: Todd Neal <todd@tneal.org>
This commit is contained in:
Keith Randall 2015-09-10 10:01:15 -07:00
parent fda72e0375
commit c7081409bb
2 changed files with 54 additions and 10 deletions

View File

@ -1693,19 +1693,22 @@ func (s *state) expr(n *Node) *ssa.Value {
a := s.expr(n.Left)
i := s.expr(n.Right)
i = s.extendIndex(i)
var elemtype *Type
var len *ssa.Value
if n.Left.Type.IsString() {
len = s.newValue1(ssa.OpStringLen, Types[TINT], a)
elemtype = Types[TUINT8]
if !n.Bounded {
len := s.newValue1(ssa.OpStringLen, Types[TINT], a)
s.boundsCheck(i, len)
}
ptrtyp := Ptrto(Types[TUINT8])
ptr := s.newValue1(ssa.OpStringPtr, ptrtyp, a)
ptr = s.newValue2(ssa.OpAddPtr, ptrtyp, ptr, i)
return s.newValue2(ssa.OpLoad, Types[TUINT8], ptr, s.mem())
} else {
len = s.constInt(Types[TINT], n.Left.Type.Bound)
elemtype = n.Left.Type.Type
if !n.Bounded {
len := s.constInt(Types[TINT], n.Left.Type.Bound)
s.boundsCheck(i, len)
}
return s.newValue2(ssa.OpArrayIndex, n.Left.Type.Type, a, i)
}
if !n.Bounded {
s.boundsCheck(i, len)
}
return s.newValue2(ssa.OpArrayIndex, elemtype, a, i)
} else { // slice
p := s.addr(n)
return s.newValue2(ssa.OpLoad, n.Left.Type.Type, p, s.mem())

View File

@ -70,6 +70,7 @@ func testStructSlice() {
p.slice_ssa()
if "pre" != p.prefix {
println("wrong field slice: wanted %s got %s", "pre", p.prefix)
failed = true
}
}
@ -114,11 +115,51 @@ func testSmallIndexType() {
}
}
func testStringElem_ssa(s string, i int) byte {
switch { // prevent inlining
}
return s[i]
}
func testStringElem() {
tests := []struct {
s string
i int
n byte
}{
{"foobar", 3, 98},
{"foobar", 0, 102},
{"foobar", 5, 114},
}
for _, t := range tests {
if got := testStringElem_ssa(t.s, t.i); got != t.n {
print("testStringElem \"", t.s, "\"[", t.i, "]=", got, ", wanted ", t.n, "\n")
failed = true
}
}
}
func testStringElemConst_ssa(i int) byte {
switch { // prevent inlining
}
s := "foobar"
return s[i]
}
func testStringElemConst() {
if got := testStringElemConst_ssa(3); got != 98 {
println("testStringElemConst=", got, ", wanted 98")
failed = true
}
}
func main() {
testStringSlice()
testStringSlicePanic()
testStructSlice()
testSmallIndexType()
testStringElem()
testStringElemConst()
if failed {
panic("failed")