return s.curBlock.NewValue2(ssa.OpLoad, n.Type, nil, p, s.mem())
case OINDEX:
- if n.Left.Type.Bound >= 0 { // array
+ if n.Left.Type.Bound >= 0 { // array or string
a := s.expr(n.Left)
i := s.expr(n.Right)
- s.boundsCheck(i, s.f.ConstInt(s.config.Uintptr, n.Left.Type.Bound))
- return s.curBlock.NewValue2(ssa.OpArrayIndex, n.Left.Type.Type, nil, a, i)
+ var elemtype *Type
+ var len *ssa.Value
+ if n.Left.Type.IsString() {
+ len = s.curBlock.NewValue1(ssa.OpStringLen, s.config.Uintptr, nil, a)
+ elemtype = Types[TUINT8]
+ } else {
+ len = s.f.ConstInt(s.config.Uintptr, n.Left.Type.Bound)
+ elemtype = n.Left.Type.Type
+ }
+ s.boundsCheck(i, len)
+ return s.curBlock.NewValue2(ssa.OpArrayIndex, elemtype, nil, a, i)
} else { // slice
p := s.addr(n)
return s.curBlock.NewValue2(ssa.OpLoad, n.Left.Type.Type, nil, p, s.mem())
}
}
-// expr converts the address of the expression n to SSA, adds it to s and returns the SSA result.
+// addr converts the address of the expression n to SSA, adds it to s and returns the SSA result.
func (s *state) addr(n *Node) *ssa.Value {
switch n.Op {
case ONAME:
return s.curBlock.NewValue2(ssa.OpPtrIndex, Ptrto(n.Left.Type.Type), nil, p, i)
}
default:
- log.Fatalf("addr: bad op %v", n.Op)
+ log.Fatalf("addr: bad op %v", Oconv(int(n.Op), 0))
return nil
}
}
var curv *Value
defer func() {
if curb != nil {
- log.Printf("panic during rewrite of %s\n", curb.LongString())
+ log.Printf("panic during rewrite of block %s\n", curb.LongString())
}
if curv != nil {
- log.Printf("panic during rewrite of %s\n", curv.LongString())
+ log.Printf("panic during rewrite of value %s\n", curv.LongString())
panic("rewrite failed")
// TODO(khr): print source location also
}