mirror of
https://github.com/golang/go
synced 2024-10-05 20:31:20 -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)
|
a := s.expr(n.Left)
|
||||||
i := s.expr(n.Right)
|
i := s.expr(n.Right)
|
||||||
i = s.extendIndex(i)
|
i = s.extendIndex(i)
|
||||||
var elemtype *Type
|
|
||||||
var len *ssa.Value
|
|
||||||
if n.Left.Type.IsString() {
|
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 {
|
if !n.Bounded {
|
||||||
|
len := s.newValue1(ssa.OpStringLen, Types[TINT], a)
|
||||||
s.boundsCheck(i, len)
|
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
|
} else { // slice
|
||||||
p := s.addr(n)
|
p := s.addr(n)
|
||||||
return s.newValue2(ssa.OpLoad, n.Left.Type.Type, p, s.mem())
|
return s.newValue2(ssa.OpLoad, n.Left.Type.Type, p, s.mem())
|
||||||
|
@ -70,6 +70,7 @@ func testStructSlice() {
|
|||||||
p.slice_ssa()
|
p.slice_ssa()
|
||||||
if "pre" != p.prefix {
|
if "pre" != p.prefix {
|
||||||
println("wrong field slice: wanted %s got %s", "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() {
|
func main() {
|
||||||
testStringSlice()
|
testStringSlice()
|
||||||
testStringSlicePanic()
|
testStringSlicePanic()
|
||||||
testStructSlice()
|
testStructSlice()
|
||||||
testSmallIndexType()
|
testSmallIndexType()
|
||||||
|
testStringElem()
|
||||||
|
testStringElemConst()
|
||||||
|
|
||||||
if failed {
|
if failed {
|
||||||
panic("failed")
|
panic("failed")
|
||||||
|
Loading…
Reference in New Issue
Block a user