if a.Op() == ir.OKEY {
kv := a.(*ir.KeyExpr)
k = typecheck.IndexConst(kv.Key)
- if k < 0 {
- base.Fatalf("initplan arraylit: invalid index %v", kv.Key)
- }
a = kv.Value
}
s.addvalue(p, k*n.Type().Elem().Size(), a)
return nil
}
-// IndexConst checks if Node n contains a constant expression
-// representable as a non-negative int and returns its value.
-// If n is not a constant expression, not representable as an
-// integer, or negative, it returns -1. If n is too large, it
-// returns -2.
+// IndexConst returns the index value of constant Node n.
func IndexConst(n ir.Node) int64 {
- if n.Op() != ir.OLITERAL {
- return -1
- }
- if !n.Type().IsInteger() && n.Type().Kind() != types.TIDEAL {
- return -1
- }
-
- v := toint(n.Val())
- if v.Kind() != constant.Int || constant.Sign(v) < 0 {
- return -1
- }
- if ir.ConstOverflow(v, types.Types[types.TINT]) {
- return -2
- }
- return ir.IntVal(types.Types[types.TINT], v)
+ return ir.IntVal(types.Types[types.TINT], toint(n.Val()))
}
// callOrChan reports whether n is a call or channel operation.
elt := elt.(*ir.KeyExpr)
elt.Key = Expr(elt.Key)
key = IndexConst(elt.Key)
- if key < 0 {
- base.Fatalf("invalid index: %v", elt.Key)
- }
kv = elt
r = elt.Value
}
// var arr [r]T
// n = arr[:l]
i := typecheck.IndexConst(r)
- if i < 0 {
- base.Fatalf("walkExpr: invalid index %v", r)
- }
// cap is constrained to [0,2^31) or [0,2^63) depending on whether
// we're in 32-bit or 64-bit systems. So it's safe to do:
if r.Op() == ir.OKEY {
kv := r.(*ir.KeyExpr)
k = typecheck.IndexConst(kv.Key)
- if k < 0 {
- base.Fatalf("fixedlit: invalid index %v", kv.Key)
- }
r = kv.Value
}
a := ir.NewIndexExpr(base.Pos, var_, ir.NewInt(base.Pos, k))
if value.Op() == ir.OKEY {
kv := value.(*ir.KeyExpr)
index = typecheck.IndexConst(kv.Key)
- if index < 0 {
- base.Fatalf("slicelit: invalid index %v", kv.Key)
- }
value = kv.Value
}
a := ir.NewIndexExpr(base.Pos, vauto, ir.NewInt(base.Pos, index))