mirror of
https://github.com/golang/go
synced 2024-10-05 18:21: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:
parent
fda72e0375
commit
c7081409bb
@ -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]
|
||||
} else {
|
||||
len = s.constInt(Types[TINT], n.Left.Type.Bound)
|
||||
elemtype = n.Left.Type.Type
|
||||
}
|
||||
if !n.Bounded {
|
||||
len := s.newValue1(ssa.OpStringLen, Types[TINT], a)
|
||||
s.boundsCheck(i, len)
|
||||
}
|
||||
return s.newValue2(ssa.OpArrayIndex, elemtype, a, i)
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
} else { // slice
|
||||
p := s.addr(n)
|
||||
return s.newValue2(ssa.OpLoad, n.Left.Type.Type, p, s.mem())
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user