"cmd/internal/src"
)
+func RangeExprType(t *types.Type) *types.Type {
+ if t.IsPtr() && t.Elem().IsArray() {
+ return t.Elem()
+ }
+ return t
+}
+
func typecheckrangeExpr(n *ir.RangeStmt) {
n.X = Expr(n.X)
-
- t := n.X.Type()
- if t == nil {
+ if n.X.Type() == nil {
return
}
+
+ t := RangeExprType(n.X.Type())
// delicate little dance. see typecheckas2
if n.Key != nil && !ir.DeclaredBy(n.Key, n) {
n.Key = AssignExpr(n.Key)
if n.Value != nil && !ir.DeclaredBy(n.Value, n) {
n.Value = AssignExpr(n.Value)
}
- if t.IsPtr() && t.Elem().IsArray() {
- t = t.Elem()
- }
- n.SetType(t)
var tk, tv *types.Type
toomany := false
n.X = o.expr(n.X, nil)
orderBody := true
- switch n.Type().Kind() {
+ xt := typecheck.RangeExprType(n.X.Type())
+ switch xt.Kind() {
default:
base.Fatalf("order.stmt range %v", n.Type())
// n.Prealloc is the temp for the iterator.
// hiter contains pointers and needs to be zeroed.
- n.Prealloc = o.newTemp(reflectdata.MapIterType(n.Type()), true)
+ n.Prealloc = o.newTemp(reflectdata.MapIterType(xt), true)
}
n.Key = o.exprInPlace(n.Key)
n.Value = o.exprInPlace(n.Value)
// hb: hidden bool
// a, v1, v2: not hidden aggregate, val 1, 2
- t := nrange.Type()
-
a := nrange.X
+ t := typecheck.RangeExprType(a.Type())
lno := ir.SetPos(a)
v1, v2 := nrange.Key, nrange.Value
}
// for v1, v2 := range ha { body }
- if cheapComputableIndex(nrange.Type().Elem().Width) {
+ if cheapComputableIndex(t.Elem().Width) {
// v1, v2 = hv1, ha[hv1]
tmp := ir.NewIndexExpr(base.Pos, ha, hv1)
tmp.SetBounded(true)
ifGuard.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, hv1, hn)
nfor.SetOp(ir.OFORUNTIL)
- hp := typecheck.Temp(types.NewPtr(nrange.Type().Elem()))
+ hp := typecheck.Temp(types.NewPtr(t.Elem()))
tmp := ir.NewIndexExpr(base.Pos, ha, ir.NewInt(0))
tmp.SetBounded(true)
init = append(init, ir.NewAssignStmt(base.Pos, hp, typecheck.NodAddr(tmp)))
return false
}
- if n.Op() != ir.ORANGE || n.Type().Kind() != types.TMAP || n.Key == nil || n.Value != nil {
+ t := n.X.Type()
+ if n.Op() != ir.ORANGE || t.Kind() != types.TMAP || n.Key == nil || n.Value != nil {
return false
}
}
// Keys where equality is not reflexive can not be deleted from maps.
- if !types.IsReflexive(m.Type().Key()) {
+ if !types.IsReflexive(t.Key()) {
return false
}
return nil
}
- elemsize := loop.Type().Elem().Width
+ elemsize := typecheck.RangeExprType(loop.X.Type()).Elem().Width
if elemsize <= 0 || !ir.IsZero(stmt.Y) {
return nil
}