Commit 1624a9c9 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: get rid of redundant Type helper functions

Replace Isfixedarray, Isslice, and Isinter with the IsArray, IsSlice,
and IsInterface methods added for SSA. Rewrite performed mechanically
using gofmt -w -r "Isfoo(t) -> t.IsFoo()".

Because the IsFoo methods panic when given a nil pointer, a handful of
call sites had to be modified to check for nil Type values. These
aren't strictly necessary, because nil Type values should only occur
in invalid Go source programs, so it would be okay if we panicked on
them and gave up type checking the rest of the package. However, there
are a couple regress tests that expect we continue, so add checks to
keep those tests passing. (See #15029.)

Passes toolstash -cmp.

Change-Id: I511c6ac4cfdf3f9cbdb3e52a5fa91b6d09d82f80
Reviewed-on: https://go-review.googlesource.com/21336Reviewed-by: default avatarJosh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 2592e099
...@@ -99,7 +99,7 @@ func algtype1(t *Type, bad **Type) int { ...@@ -99,7 +99,7 @@ func algtype1(t *Type, bad **Type) int {
return AINTER return AINTER
case TARRAY: case TARRAY:
if Isslice(t) { if t.IsSlice() {
if bad != nil { if bad != nil {
*bad = t *bad = t
} }
...@@ -196,7 +196,7 @@ func genhash(sym *Sym, t *Type) { ...@@ -196,7 +196,7 @@ func genhash(sym *Sym, t *Type) {
Fatalf("genhash %v", t) Fatalf("genhash %v", t)
case TARRAY: case TARRAY:
if Isslice(t) { if t.IsSlice() {
Fatalf("genhash %v", t) Fatalf("genhash %v", t)
} }
...@@ -375,7 +375,7 @@ func geneq(sym *Sym, t *Type) { ...@@ -375,7 +375,7 @@ func geneq(sym *Sym, t *Type) {
Fatalf("geneq %v", t) Fatalf("geneq %v", t)
case TARRAY: case TARRAY:
if Isslice(t) { if t.IsSlice() {
Fatalf("geneq %v", t) Fatalf("geneq %v", t)
} }
......
...@@ -174,12 +174,12 @@ func cgen_wb(n, res *Node, wb bool) { ...@@ -174,12 +174,12 @@ func cgen_wb(n, res *Node, wb bool) {
// changes if n->left is an escaping local variable. // changes if n->left is an escaping local variable.
switch n.Op { switch n.Op {
case OSPTR, OLEN: case OSPTR, OLEN:
if Isslice(n.Left.Type) || Istype(n.Left.Type, TSTRING) { if n.Left.Type.IsSlice() || Istype(n.Left.Type, TSTRING) {
n.Addable = n.Left.Addable n.Addable = n.Left.Addable
} }
case OCAP: case OCAP:
if Isslice(n.Left.Type) { if n.Left.Type.IsSlice() {
n.Addable = n.Left.Addable n.Addable = n.Left.Addable
} }
...@@ -578,7 +578,7 @@ func cgen_wb(n, res *Node, wb bool) { ...@@ -578,7 +578,7 @@ func cgen_wb(n, res *Node, wb bool) {
break break
} }
if Istype(nl.Type, TSTRING) || Isslice(nl.Type) { if Istype(nl.Type, TSTRING) || nl.Type.IsSlice() {
// both slice and string have len one pointer into the struct. // both slice and string have len one pointer into the struct.
// a zero pointer means zero length // a zero pointer means zero length
var n1 Node var n1 Node
...@@ -619,7 +619,7 @@ func cgen_wb(n, res *Node, wb bool) { ...@@ -619,7 +619,7 @@ func cgen_wb(n, res *Node, wb bool) {
break break
} }
if Isslice(nl.Type) { if nl.Type.IsSlice() {
var n1 Node var n1 Node
Igen(nl, &n1, res) Igen(nl, &n1, res)
n1.Type = Types[Simtype[TUINT]] n1.Type = Types[Simtype[TUINT]]
...@@ -1034,7 +1034,7 @@ func Agenr(n *Node, a *Node, res *Node) { ...@@ -1034,7 +1034,7 @@ func Agenr(n *Node, a *Node, res *Node) {
} }
v := uint64(nr.Val().U.(*Mpint).Int64()) v := uint64(nr.Val().U.(*Mpint).Int64())
var n2 Node var n2 Node
if Isslice(nl.Type) || nl.Type.Etype == TSTRING { if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
if Debug['B'] == 0 && !n.Bounded { if Debug['B'] == 0 && !n.Bounded {
n1 = n3 n1 = n3
n1.Op = OINDREG n1.Op = OINDREG
...@@ -1069,7 +1069,7 @@ func Agenr(n *Node, a *Node, res *Node) { ...@@ -1069,7 +1069,7 @@ func Agenr(n *Node, a *Node, res *Node) {
// check bounds // check bounds
if Isconst(nl, CTSTR) { if Isconst(nl, CTSTR) {
Nodconst(&n4, Types[TUINT32], int64(len(nl.Val().U.(string)))) Nodconst(&n4, Types[TUINT32], int64(len(nl.Val().U.(string))))
} else if Isslice(nl.Type) || nl.Type.Etype == TSTRING { } else if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
n1 = n3 n1 = n3
n1.Op = OINDREG n1.Op = OINDREG
n1.Type = Types[Tptr] n1.Type = Types[Tptr]
...@@ -1095,7 +1095,7 @@ func Agenr(n *Node, a *Node, res *Node) { ...@@ -1095,7 +1095,7 @@ func Agenr(n *Node, a *Node, res *Node) {
p1 := Thearch.Gins(Thearch.Optoas(OAS, Types[Tptr]), nil, &n3) p1 := Thearch.Gins(Thearch.Optoas(OAS, Types[Tptr]), nil, &n3)
Datastring(nl.Val().U.(string), &p1.From) Datastring(nl.Val().U.(string), &p1.From)
p1.From.Type = obj.TYPE_ADDR p1.From.Type = obj.TYPE_ADDR
} else if Isslice(nl.Type) || nl.Type.Etype == TSTRING { } else if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
n1 = n3 n1 = n3
n1.Op = OINDREG n1.Op = OINDREG
n1.Type = Types[Tptr] n1.Type = Types[Tptr]
...@@ -1167,7 +1167,7 @@ func Agenr(n *Node, a *Node, res *Node) { ...@@ -1167,7 +1167,7 @@ func Agenr(n *Node, a *Node, res *Node) {
// For fixed array we really want the pointer in n3. // For fixed array we really want the pointer in n3.
var n2 Node var n2 Node
if Isfixedarray(nl.Type) { if nl.Type.IsArray() {
Regalloc(&n2, Types[Tptr], &n3) Regalloc(&n2, Types[Tptr], &n3)
Agen(&n3, &n2) Agen(&n3, &n2)
Regfree(&n3) Regfree(&n3)
...@@ -1185,7 +1185,7 @@ func Agenr(n *Node, a *Node, res *Node) { ...@@ -1185,7 +1185,7 @@ func Agenr(n *Node, a *Node, res *Node) {
Fatalf("constant string constant index") // front end should handle Fatalf("constant string constant index") // front end should handle
} }
v := uint64(nr.Val().U.(*Mpint).Int64()) v := uint64(nr.Val().U.(*Mpint).Int64())
if Isslice(nl.Type) || nl.Type.Etype == TSTRING { if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
if Debug['B'] == 0 && !n.Bounded { if Debug['B'] == 0 && !n.Bounded {
nlen := n3 nlen := n3
nlen.Type = Types[TUINT32] nlen.Type = Types[TUINT32]
...@@ -1230,7 +1230,7 @@ func Agenr(n *Node, a *Node, res *Node) { ...@@ -1230,7 +1230,7 @@ func Agenr(n *Node, a *Node, res *Node) {
var nlen Node var nlen Node
if Isconst(nl, CTSTR) { if Isconst(nl, CTSTR) {
Nodconst(&nlen, t, int64(len(nl.Val().U.(string)))) Nodconst(&nlen, t, int64(len(nl.Val().U.(string))))
} else if Isslice(nl.Type) || nl.Type.Etype == TSTRING { } else if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
nlen = n3 nlen = n3
nlen.Type = t nlen.Type = t
nlen.Xoffset += int64(Array_nel) nlen.Xoffset += int64(Array_nel)
...@@ -1258,7 +1258,7 @@ func Agenr(n *Node, a *Node, res *Node) { ...@@ -1258,7 +1258,7 @@ func Agenr(n *Node, a *Node, res *Node) {
// Load base pointer in n3. // Load base pointer in n3.
Regalloc(&tmp, Types[Tptr], &n3) Regalloc(&tmp, Types[Tptr], &n3)
if Isslice(nl.Type) || nl.Type.Etype == TSTRING { if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
n3.Type = Types[Tptr] n3.Type = Types[Tptr]
n3.Xoffset += int64(Array_array) n3.Xoffset += int64(Array_array)
Thearch.Gmove(&n3, &tmp) Thearch.Gmove(&n3, &tmp)
...@@ -1304,7 +1304,7 @@ func Agenr(n *Node, a *Node, res *Node) { ...@@ -1304,7 +1304,7 @@ func Agenr(n *Node, a *Node, res *Node) {
if nl.Addable { if nl.Addable {
Cgenr(nr, &n1, nil) Cgenr(nr, &n1, nil)
if !Isconst(nl, CTSTR) { if !Isconst(nl, CTSTR) {
if Isfixedarray(nl.Type) { if nl.Type.IsArray() {
Agenr(nl, &n3, res) Agenr(nl, &n3, res)
} else { } else {
Igen(nl, &nlen, res) Igen(nl, &nlen, res)
...@@ -1327,7 +1327,7 @@ func Agenr(n *Node, a *Node, res *Node) { ...@@ -1327,7 +1327,7 @@ func Agenr(n *Node, a *Node, res *Node) {
irad: irad:
if !Isconst(nl, CTSTR) { if !Isconst(nl, CTSTR) {
if Isfixedarray(nl.Type) { if nl.Type.IsArray() {
Agenr(nl, &n3, res) Agenr(nl, &n3, res)
} else { } else {
if !nl.Addable { if !nl.Addable {
...@@ -1375,7 +1375,7 @@ func Agenr(n *Node, a *Node, res *Node) { ...@@ -1375,7 +1375,7 @@ func Agenr(n *Node, a *Node, res *Node) {
Fatalf("constant string constant index") // front end should handle Fatalf("constant string constant index") // front end should handle
} }
v := uint64(nr.Val().U.(*Mpint).Int64()) v := uint64(nr.Val().U.(*Mpint).Int64())
if Isslice(nl.Type) || nl.Type.Etype == TSTRING { if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
if Debug['B'] == 0 && !n.Bounded { if Debug['B'] == 0 && !n.Bounded {
p1 := Thearch.Ginscmp(OGT, Types[Simtype[TUINT]], &nlen, Nodintconst(int64(v)), +1) p1 := Thearch.Ginscmp(OGT, Types[Simtype[TUINT]], &nlen, Nodintconst(int64(v)), +1)
Ginscall(Panicindex, -1) Ginscall(Panicindex, -1)
...@@ -1413,7 +1413,7 @@ func Agenr(n *Node, a *Node, res *Node) { ...@@ -1413,7 +1413,7 @@ func Agenr(n *Node, a *Node, res *Node) {
} }
if Isconst(nl, CTSTR) { if Isconst(nl, CTSTR) {
Nodconst(&nlen, t, int64(len(nl.Val().U.(string)))) Nodconst(&nlen, t, int64(len(nl.Val().U.(string))))
} else if Isslice(nl.Type) || nl.Type.Etype == TSTRING { } else if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
// nlen already initialized // nlen already initialized
} else { } else {
Nodconst(&nlen, t, nl.Type.Bound) Nodconst(&nlen, t, nl.Type.Bound)
...@@ -1690,7 +1690,7 @@ func Igen(n *Node, a *Node, res *Node) { ...@@ -1690,7 +1690,7 @@ func Igen(n *Node, a *Node, res *Node) {
// Could do the same for slice except that we need // Could do the same for slice except that we need
// to use the real index for the bounds checking. // to use the real index for the bounds checking.
case OINDEX: case OINDEX:
if Isfixedarray(n.Left.Type) || (Isptr[n.Left.Type.Etype] && Isfixedarray(n.Left.Left.Type)) { if n.Left.Type.IsArray() || (Isptr[n.Left.Type.Etype] && n.Left.Left.Type.IsArray()) {
if Isconst(n.Right, CTINT) { if Isconst(n.Right, CTINT) {
// Compute &a. // Compute &a.
if !Isptr[n.Left.Type.Etype] { if !Isptr[n.Left.Type.Etype] {
...@@ -1946,10 +1946,10 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) { ...@@ -1946,10 +1946,10 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
nl, nr = nr, nl nl, nr = nr, nl
} }
if Isslice(nl.Type) || Isinter(nl.Type) { if nl.Type.IsSlice() || nl.Type.IsInterface() {
// front end should only leave cmp to literal nil // front end should only leave cmp to literal nil
if (op != OEQ && op != ONE) || nr.Op != OLITERAL { if (op != OEQ && op != ONE) || nr.Op != OLITERAL {
if Isslice(nl.Type) { if nl.Type.IsSlice() {
Yyerror("illegal slice comparison") Yyerror("illegal slice comparison")
} else { } else {
Yyerror("illegal interface comparison") Yyerror("illegal interface comparison")
...@@ -1959,7 +1959,7 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) { ...@@ -1959,7 +1959,7 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
var ptr Node var ptr Node
Igen(nl, &ptr, nil) Igen(nl, &ptr, nil)
if Isslice(nl.Type) { if nl.Type.IsSlice() {
ptr.Xoffset += int64(Array_array) ptr.Xoffset += int64(Array_array)
} }
ptr.Type = Types[Tptr] ptr.Type = Types[Tptr]
...@@ -2206,7 +2206,7 @@ func stkof(n *Node) int64 { ...@@ -2206,7 +2206,7 @@ func stkof(n *Node) int64 {
case OINDEX: case OINDEX:
t := n.Left.Type t := n.Left.Type
if !Isfixedarray(t) { if !t.IsArray() {
break break
} }
off := stkof(n.Left) off := stkof(n.Left)
......
...@@ -582,7 +582,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node { ...@@ -582,7 +582,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node {
ptr.Xoffset = 0 ptr.Xoffset = 0
xfunc.Func.Dcl = append(xfunc.Func.Dcl, ptr) xfunc.Func.Dcl = append(xfunc.Func.Dcl, ptr)
var body []*Node var body []*Node
if Isptr[rcvrtype.Etype] || Isinter(rcvrtype) { if Isptr[rcvrtype.Etype] || rcvrtype.IsInterface() {
ptr.Name.Param.Ntype = typenod(rcvrtype) ptr.Name.Param.Ntype = typenod(rcvrtype)
body = append(body, Nod(OAS, ptr, cv)) body = append(body, Nod(OAS, ptr, cv))
} else { } else {
...@@ -622,7 +622,7 @@ func walkpartialcall(n *Node, init *Nodes) *Node { ...@@ -622,7 +622,7 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
// //
// Like walkclosure above. // Like walkclosure above.
if Isinter(n.Left.Type) { if n.Left.Type.IsInterface() {
// Trigger panic for method on nil interface now. // Trigger panic for method on nil interface now.
// Otherwise it happens in the wrapper and is confusing. // Otherwise it happens in the wrapper and is confusing.
n.Left = cheapexpr(n.Left, init) n.Left = cheapexpr(n.Left, init)
......
...@@ -231,7 +231,7 @@ func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node { ...@@ -231,7 +231,7 @@ func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node {
return n return n
case TARRAY: case TARRAY:
if !Isslice(t) { if !t.IsSlice() {
goto bad goto bad
} }
...@@ -1686,7 +1686,7 @@ func isgoconst(n *Node) bool { ...@@ -1686,7 +1686,7 @@ func isgoconst(n *Node) bool {
if t != nil && Isptr[t.Etype] { if t != nil && Isptr[t.Etype] {
t = t.Elem() t = t.Elem()
} }
if Isfixedarray(t) && !hascallchan(l) { if t != nil && t.IsArray() && !hascallchan(l) {
return true return true
} }
......
...@@ -696,7 +696,7 @@ func esc(e *EscState, n *Node, up *Node) { ...@@ -696,7 +696,7 @@ func esc(e *EscState, n *Node, up *Node) {
// If fixed array is really the address of fixed array, // If fixed array is really the address of fixed array,
// it is also a dereference, because it is implicitly // it is also a dereference, because it is implicitly
// dereferenced (see #12588) // dereferenced (see #12588)
if Isfixedarray(n.Type) && if n.Type.IsArray() &&
!(Isptr[n.Right.Type.Etype] && Eqtype(n.Right.Type.Elem(), n.Type)) { !(Isptr[n.Right.Type.Etype] && Eqtype(n.Right.Type.Elem(), n.Type)) {
escassignNilWhy(e, n.List.Second(), n.Right, "range") escassignNilWhy(e, n.List.Second(), n.Right, "range")
} else { } else {
...@@ -864,7 +864,7 @@ func esc(e *EscState, n *Node, up *Node) { ...@@ -864,7 +864,7 @@ func esc(e *EscState, n *Node, up *Node) {
case OARRAYLIT: case OARRAYLIT:
why := "array literal element" why := "array literal element"
if Isslice(n.Type) { if n.Type.IsSlice() {
// Slice itself is not leaked until proven otherwise // Slice itself is not leaked until proven otherwise
e.track(n) e.track(n)
why = "slice literal element" why = "slice literal element"
...@@ -1037,7 +1037,7 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) { ...@@ -1037,7 +1037,7 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
return return
case OINDEX: case OINDEX:
if Isfixedarray(dst.Left.Type) { if dst.Left.Type.IsArray() {
escassign(e, dst.Left, src, e.stepAssign(step, originalDst, src, "array-element-equals")) escassign(e, dst.Left, src, e.stepAssign(step, originalDst, src, "array-element-equals"))
return return
} }
...@@ -1139,7 +1139,7 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) { ...@@ -1139,7 +1139,7 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
case OINDEX: case OINDEX:
// Index of array preserves input value. // Index of array preserves input value.
if Isfixedarray(src.Left.Type) { if src.Left.Type.IsArray() {
escassign(e, dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy)) escassign(e, dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))
} else { } else {
escflows(e, dst, src, e.stepAssign(step, originalDst, src, dstwhy)) escflows(e, dst, src, e.stepAssign(step, originalDst, src, dstwhy))
...@@ -1866,7 +1866,7 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep, ...@@ -1866,7 +1866,7 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
level = level.dec() level = level.dec()
case OARRAYLIT: case OARRAYLIT:
if Isfixedarray(src.Type) { if src.Type.IsArray() {
break break
} }
for _, n1 := range src.List.Slice() { for _, n1 := range src.List.Slice() {
...@@ -1911,7 +1911,7 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep, ...@@ -1911,7 +1911,7 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
escwalk(e, level, dst, src.Left, e.stepWalk(dst, src.Left, "slice", step)) escwalk(e, level, dst, src.Left, e.stepWalk(dst, src.Left, "slice", step))
case OINDEX: case OINDEX:
if Isfixedarray(src.Left.Type) { if src.Left.Type.IsArray() {
escwalk(e, level, dst, src.Left, e.stepWalk(dst, src.Left, "fixed-array-index-of", step)) escwalk(e, level, dst, src.Left, e.stepWalk(dst, src.Left, "fixed-array-index-of", step))
break break
} }
......
...@@ -98,7 +98,7 @@ func addrescapes(n *Node) { ...@@ -98,7 +98,7 @@ func addrescapes(n *Node) {
// escape--the pointer inside x does, but that // escape--the pointer inside x does, but that
// is always a heap pointer anyway. // is always a heap pointer anyway.
case ODOT, OINDEX, OPAREN, OCONVNOP: case ODOT, OINDEX, OPAREN, OCONVNOP:
if !Isslice(n.Left.Type) { if !n.Left.Type.IsSlice() {
addrescapes(n.Left) addrescapes(n.Left)
} }
} }
...@@ -1204,7 +1204,7 @@ func visitComponents(t *Type, startOffset int64, f func(elem *Type, elemOffset i ...@@ -1204,7 +1204,7 @@ func visitComponents(t *Type, startOffset int64, f func(elem *Type, elemOffset i
f(Types[Simtype[TUINT]], startOffset+int64(Widthptr)) f(Types[Simtype[TUINT]], startOffset+int64(Widthptr))
case TARRAY: case TARRAY:
if Isslice(t) { if t.IsSlice() {
return f(Ptrto(t.Elem()), startOffset+int64(Array_array)) && return f(Ptrto(t.Elem()), startOffset+int64(Array_array)) &&
f(Types[Simtype[TUINT]], startOffset+int64(Array_nel)) && f(Types[Simtype[TUINT]], startOffset+int64(Array_nel)) &&
f(Types[Simtype[TUINT]], startOffset+int64(Array_cap)) f(Types[Simtype[TUINT]], startOffset+int64(Array_cap))
......
...@@ -150,7 +150,7 @@ func ordersafeexpr(n *Node, order *Order) *Node { ...@@ -150,7 +150,7 @@ func ordersafeexpr(n *Node, order *Order) *Node {
case OINDEX, OINDEXMAP: case OINDEX, OINDEXMAP:
var l *Node var l *Node
if Isfixedarray(n.Left.Type) { if n.Left.Type.IsArray() {
l = ordersafeexpr(n.Left, order) l = ordersafeexpr(n.Left, order)
} else { } else {
l = ordercheapexpr(n.Left, order) l = ordercheapexpr(n.Left, order)
...@@ -701,7 +701,7 @@ func orderstmt(n *Node, order *Order) { ...@@ -701,7 +701,7 @@ func orderstmt(n *Node, order *Order) {
t := marktemp(order) t := marktemp(order)
n.Left = orderexpr(n.Left, order, nil) n.Left = orderexpr(n.Left, order, nil)
if !Isinter(n.Left.Type) { if !n.Left.Type.IsInterface() {
n.Left = orderaddrtemp(n.Left, order) n.Left = orderaddrtemp(n.Left, order)
} }
order.out = append(order.out, n) order.out = append(order.out, n)
...@@ -1078,7 +1078,7 @@ func orderexpr(n *Node, order *Order, lhs *Node) *Node { ...@@ -1078,7 +1078,7 @@ func orderexpr(n *Node, order *Order, lhs *Node) *Node {
case OCONVIFACE: case OCONVIFACE:
n.Left = orderexpr(n.Left, order, nil) n.Left = orderexpr(n.Left, order, nil)
if !Isinter(n.Left.Type) { if !n.Left.Type.IsInterface() {
n.Left = orderaddrtemp(n.Left, order) n.Left = orderaddrtemp(n.Left, order)
} }
...@@ -1185,7 +1185,7 @@ func orderexpr(n *Node, order *Order, lhs *Node) *Node { ...@@ -1185,7 +1185,7 @@ func orderexpr(n *Node, order *Order, lhs *Node) *Node {
n.Left = orderexpr(n.Left, order, nil) n.Left = orderexpr(n.Left, order, nil)
n.Right = orderexpr(n.Right, order, nil) n.Right = orderexpr(n.Right, order, nil)
t := n.Left.Type t := n.Left.Type
if t.Etype == TSTRUCT || Isfixedarray(t) { if t.Etype == TSTRUCT || t.IsArray() {
// for complex comparisons, we need both args to be // for complex comparisons, we need both args to be
// addressable so we can pass them to the runtime. // addressable so we can pass them to the runtime.
n.Left = orderaddrtemp(n.Left, order) n.Left = orderaddrtemp(n.Left, order)
......
...@@ -923,7 +923,7 @@ func onebitwalktype1(t *Type, xoffset *int64, bv Bvec) { ...@@ -923,7 +923,7 @@ func onebitwalktype1(t *Type, xoffset *int64, bv Bvec) {
if t.Bound < -1 { if t.Bound < -1 {
Fatalf("onebitwalktype1: invalid bound, %v", t) Fatalf("onebitwalktype1: invalid bound, %v", t)
} }
if Isslice(t) { if t.IsSlice() {
// struct { byte *array; uintgo len; uintgo cap; } // struct { byte *array; uintgo len; uintgo cap; }
if *xoffset&int64(Widthptr-1) != 0 { if *xoffset&int64(Widthptr-1) != 0 {
Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t) Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t)
......
...@@ -283,7 +283,7 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) { ...@@ -283,7 +283,7 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) {
goto ret goto ret
case OINDEX: case OINDEX:
if !Isfixedarray(n.Left.Type) { if !n.Left.Type.IsArray() {
instrumentnode(&n.Left, init, 0, 0) instrumentnode(&n.Left, init, 0, 0)
} else if !islvalue(n.Left) { } else if !islvalue(n.Left) {
// index of unaddressable array, like Map[k][i]. // index of unaddressable array, like Map[k][i].
...@@ -509,7 +509,7 @@ func callinstr(np **Node, init *Nodes, wr int, skip int) bool { ...@@ -509,7 +509,7 @@ func callinstr(np **Node, init *Nodes, wr int, skip int) bool {
Fatalf("instrument: %v badwidth", t) Fatalf("instrument: %v badwidth", t)
} }
f = mkcall(name, nil, init, uintptraddr(n), Nodintconst(w)) f = mkcall(name, nil, init, uintptraddr(n), Nodintconst(w))
} else if flag_race != 0 && (t.Etype == TSTRUCT || Isfixedarray(t)) { } else if flag_race != 0 && (t.Etype == TSTRUCT || t.IsArray()) {
name := "racereadrange" name := "racereadrange"
if wr != 0 { if wr != 0 {
name = "racewriterange" name = "racewriterange"
...@@ -548,7 +548,7 @@ func makeaddable(n *Node) { ...@@ -548,7 +548,7 @@ func makeaddable(n *Node) {
// an addressable value. // an addressable value.
switch n.Op { switch n.Op {
case OINDEX: case OINDEX:
if Isfixedarray(n.Left.Type) { if n.Left.Type.IsArray() {
makeaddable(n.Left) makeaddable(n.Left)
} }
......
...@@ -38,7 +38,7 @@ func typecheckrange(n *Node) { ...@@ -38,7 +38,7 @@ func typecheckrange(n *Node) {
} }
} }
if Isptr[t.Etype] && Isfixedarray(t.Elem()) { if Isptr[t.Etype] && t.Elem().IsArray() {
t = t.Elem() t = t.Elem()
} }
n.Type = t n.Type = t
......
...@@ -743,7 +743,7 @@ func typeptrdata(t *Type) int64 { ...@@ -743,7 +743,7 @@ func typeptrdata(t *Type) int64 {
return 2 * int64(Widthptr) return 2 * int64(Widthptr)
case TARRAY: case TARRAY:
if Isslice(t) { if t.IsSlice() {
// struct { byte *array; uintgo len; uintgo cap; } // struct { byte *array; uintgo len; uintgo cap; }
return int64(Widthptr) return int64(Widthptr)
} }
...@@ -999,7 +999,7 @@ func isreflexive(t *Type) bool { ...@@ -999,7 +999,7 @@ func isreflexive(t *Type) bool {
return false return false
case TARRAY: case TARRAY:
if Isslice(t) { if t.IsSlice() {
Fatalf("slice can't be a map key: %v", t) Fatalf("slice can't be a map key: %v", t)
} }
return isreflexive(t.Elem()) return isreflexive(t.Elem())
...@@ -1049,7 +1049,7 @@ func needkeyupdate(t *Type) bool { ...@@ -1049,7 +1049,7 @@ func needkeyupdate(t *Type) bool {
return true return true
case TARRAY: case TARRAY:
if Isslice(t) { if t.IsSlice() {
Fatalf("slice can't be a map key: %v", t) Fatalf("slice can't be a map key: %v", t)
} }
return needkeyupdate(t.Elem()) return needkeyupdate(t.Elem())
...@@ -1633,7 +1633,7 @@ func (p *GCProg) emit(t *Type, offset int64) { ...@@ -1633,7 +1633,7 @@ func (p *GCProg) emit(t *Type, offset int64) {
p.w.Ptr(offset/int64(Widthptr) + 1) p.w.Ptr(offset/int64(Widthptr) + 1)
case TARRAY: case TARRAY:
if Isslice(t) { if t.IsSlice() {
p.w.Ptr(offset / int64(Widthptr)) p.w.Ptr(offset / int64(Widthptr))
return return
} }
...@@ -1645,7 +1645,7 @@ func (p *GCProg) emit(t *Type, offset int64) { ...@@ -1645,7 +1645,7 @@ func (p *GCProg) emit(t *Type, offset int64) {
// Flatten array-of-array-of-array to just a big array by multiplying counts. // Flatten array-of-array-of-array to just a big array by multiplying counts.
count := t.Bound count := t.Bound
elem := t.Elem() elem := t.Elem()
for Isfixedarray(elem) { for elem.IsArray() {
count *= elem.Bound count *= elem.Bound
elem = elem.Elem() elem = elem.Elem()
} }
......
...@@ -328,7 +328,7 @@ func staticcopy(l *Node, r *Node, out *[]*Node) bool { ...@@ -328,7 +328,7 @@ func staticcopy(l *Node, r *Node, out *[]*Node) bool {
} }
case OARRAYLIT: case OARRAYLIT:
if Isslice(r.Type) { if r.Type.IsSlice() {
// copy slice // copy slice
a := inittemps[r] a := inittemps[r]
...@@ -431,7 +431,7 @@ func staticassign(l *Node, r *Node, out *[]*Node) bool { ...@@ -431,7 +431,7 @@ func staticassign(l *Node, r *Node, out *[]*Node) bool {
case OARRAYLIT: case OARRAYLIT:
initplan(r) initplan(r)
if Isslice(r.Type) { if r.Type.IsSlice() {
// Init slice. // Init slice.
bound := r.Right.Val().U.(*Mpint).Int64() bound := r.Right.Val().U.(*Mpint).Int64()
ta := typArray(r.Type.Elem(), bound) ta := typArray(r.Type.Elem(), bound)
...@@ -1304,7 +1304,7 @@ func iszero(n *Node) bool { ...@@ -1304,7 +1304,7 @@ func iszero(n *Node) bool {
} }
case OARRAYLIT: case OARRAYLIT:
if Isslice(n.Type) { if n.Type.IsSlice() {
break break
} }
fallthrough fallthrough
...@@ -1323,7 +1323,7 @@ func iszero(n *Node) bool { ...@@ -1323,7 +1323,7 @@ func iszero(n *Node) bool {
} }
func isvaluelit(n *Node) bool { func isvaluelit(n *Node) bool {
return (n.Op == OARRAYLIT && Isfixedarray(n.Type)) || n.Op == OSTRUCTLIT return (n.Op == OARRAYLIT && n.Type.IsArray()) || n.Op == OSTRUCTLIT
} }
// gen_as_init attempts to emit static data for n and reports whether it succeeded. // gen_as_init attempts to emit static data for n and reports whether it succeeded.
......
...@@ -2768,7 +2768,7 @@ func canSSAType(t *Type) bool { ...@@ -2768,7 +2768,7 @@ func canSSAType(t *Type) bool {
} }
switch t.Etype { switch t.Etype {
case TARRAY: case TARRAY:
if Isslice(t) { if t.IsSlice() {
return true return true
} }
// We can't do arrays because dynamic indexing is // We can't do arrays because dynamic indexing is
......
...@@ -579,14 +579,6 @@ func Istype(t *Type, et EType) bool { ...@@ -579,14 +579,6 @@ func Istype(t *Type, et EType) bool {
return t != nil && t.Etype == et return t != nil && t.Etype == et
} }
func Isfixedarray(t *Type) bool {
return t != nil && t.IsArray()
}
func Isslice(t *Type) bool {
return t != nil && t.IsSlice()
}
func isblank(n *Node) bool { func isblank(n *Node) bool {
if n == nil { if n == nil {
return false return false
...@@ -598,12 +590,8 @@ func isblanksym(s *Sym) bool { ...@@ -598,12 +590,8 @@ func isblanksym(s *Sym) bool {
return s != nil && s.Name == "_" return s != nil && s.Name == "_"
} }
func Isinter(t *Type) bool {
return t != nil && t.Etype == TINTER
}
func isnilinter(t *Type) bool { func isnilinter(t *Type) bool {
return Isinter(t) && t.NumFields() == 0 return t.IsInterface() && t.NumFields() == 0
} }
func isideal(t *Type) bool { func isideal(t *Type) bool {
...@@ -987,7 +975,7 @@ func convertop(src *Type, dst *Type, why *string) Op { ...@@ -987,7 +975,7 @@ func convertop(src *Type, dst *Type, why *string) Op {
return ORUNESTR return ORUNESTR
} }
if Isslice(src) && dst.Etype == TSTRING { if src.IsSlice() && dst.Etype == TSTRING {
if src.Elem().Etype == bytetype.Etype { if src.Elem().Etype == bytetype.Etype {
return OARRAYBYTESTR return OARRAYBYTESTR
} }
...@@ -998,7 +986,7 @@ func convertop(src *Type, dst *Type, why *string) Op { ...@@ -998,7 +986,7 @@ func convertop(src *Type, dst *Type, why *string) Op {
// 7. src is a string and dst is []byte or []rune. // 7. src is a string and dst is []byte or []rune.
// String to slice. // String to slice.
if src.Etype == TSTRING && Isslice(dst) { if src.Etype == TSTRING && dst.IsSlice() {
if dst.Elem().Etype == bytetype.Etype { if dst.Elem().Etype == bytetype.Etype {
return OSTRARRAYBYTE return OSTRARRAYBYTE
} }
...@@ -2249,7 +2237,7 @@ func isbadimport(path string) bool { ...@@ -2249,7 +2237,7 @@ func isbadimport(path string) bool {
} }
func checknil(x *Node, init *Nodes) { func checknil(x *Node, init *Nodes) {
if Isinter(x.Type) { if x.Type.IsInterface() {
x = Nod(OITAB, x, nil) x = Nod(OITAB, x, nil)
x = typecheck(x, Erv) x = typecheck(x, Erv)
} }
...@@ -2290,7 +2278,7 @@ func (t *Type) iet() byte { ...@@ -2290,7 +2278,7 @@ func (t *Type) iet() byte {
if isnilinter(t) { if isnilinter(t) {
return 'E' return 'E'
} }
if Isinter(t) { if t.IsInterface() {
return 'I' return 'I'
} }
return 'T' return 'T'
......
...@@ -87,9 +87,9 @@ func typecheckswitch(n *Node) { ...@@ -87,9 +87,9 @@ func typecheckswitch(n *Node) {
switch { switch {
case !okforeq[t.Etype]: case !okforeq[t.Etype]:
Yyerror("cannot switch on %v", Nconv(n.Left, FmtLong)) Yyerror("cannot switch on %v", Nconv(n.Left, FmtLong))
case t.Etype == TARRAY && !Isfixedarray(t): case t.Etype == TARRAY && !t.IsArray():
nilonly = "slice" nilonly = "slice"
case t.Etype == TARRAY && Isfixedarray(t) && algtype1(t, nil) == ANOEQ: case t.Etype == TARRAY && t.IsArray() && algtype1(t, nil) == ANOEQ:
Yyerror("cannot switch on %v", Nconv(n.Left, FmtLong)) Yyerror("cannot switch on %v", Nconv(n.Left, FmtLong))
case t.Etype == TSTRUCT && algtype1(t, &badtype) == ANOEQ: case t.Etype == TSTRUCT && algtype1(t, &badtype) == ANOEQ:
Yyerror("cannot switch on %v (struct containing %v cannot be compared)", Nconv(n.Left, FmtLong), badtype) Yyerror("cannot switch on %v (struct containing %v cannot be compared)", Nconv(n.Left, FmtLong), badtype)
...@@ -139,7 +139,7 @@ func typecheckswitch(n *Node) { ...@@ -139,7 +139,7 @@ func typecheckswitch(n *Node) {
} }
case nilonly != "" && !isnil(n1): case nilonly != "" && !isnil(n1):
Yyerror("invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left) Yyerror("invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left)
case Isinter(t) && !Isinter(n1.Type) && algtype1(n1.Type, nil) == ANOEQ: case t.IsInterface() && !n1.Type.IsInterface() && algtype1(n1.Type, nil) == ANOEQ:
Yyerror("invalid case %v in switch (incomparable type)", Nconv(n1, FmtLong)) Yyerror("invalid case %v in switch (incomparable type)", Nconv(n1, FmtLong))
} }
......
...@@ -72,7 +72,7 @@ var _typekind = []string{ ...@@ -72,7 +72,7 @@ var _typekind = []string{
} }
func typekind(t *Type) string { func typekind(t *Type) string {
if Isslice(t) { if t.IsSlice() {
return "slice" return "slice"
} }
et := t.Etype et := t.Etype
...@@ -595,14 +595,14 @@ OpSwitch: ...@@ -595,14 +595,14 @@ OpSwitch:
if r.Type.Etype != TBLANK { if r.Type.Etype != TBLANK {
aop = assignop(l.Type, r.Type, nil) aop = assignop(l.Type, r.Type, nil)
if aop != 0 { if aop != 0 {
if Isinter(r.Type) && !Isinter(l.Type) && algtype1(l.Type, nil) == ANOEQ { if r.Type.IsInterface() && !l.Type.IsInterface() && algtype1(l.Type, nil) == ANOEQ {
Yyerror("invalid operation: %v (operator %v not defined on %s)", n, Oconv(op, 0), typekind(l.Type)) Yyerror("invalid operation: %v (operator %v not defined on %s)", n, Oconv(op, 0), typekind(l.Type))
n.Type = nil n.Type = nil
return n return n
} }
dowidth(l.Type) dowidth(l.Type)
if Isinter(r.Type) == Isinter(l.Type) || l.Type.Width >= 1<<16 { if r.Type.IsInterface() == l.Type.IsInterface() || l.Type.Width >= 1<<16 {
l = Nod(aop, l, nil) l = Nod(aop, l, nil)
l.Type = r.Type l.Type = r.Type
l.Typecheck = 1 l.Typecheck = 1
...@@ -617,14 +617,14 @@ OpSwitch: ...@@ -617,14 +617,14 @@ OpSwitch:
if l.Type.Etype != TBLANK { if l.Type.Etype != TBLANK {
aop = assignop(r.Type, l.Type, nil) aop = assignop(r.Type, l.Type, nil)
if aop != 0 { if aop != 0 {
if Isinter(l.Type) && !Isinter(r.Type) && algtype1(r.Type, nil) == ANOEQ { if l.Type.IsInterface() && !r.Type.IsInterface() && algtype1(r.Type, nil) == ANOEQ {
Yyerror("invalid operation: %v (operator %v not defined on %s)", n, Oconv(op, 0), typekind(r.Type)) Yyerror("invalid operation: %v (operator %v not defined on %s)", n, Oconv(op, 0), typekind(r.Type))
n.Type = nil n.Type = nil
return n return n
} }
dowidth(r.Type) dowidth(r.Type)
if Isinter(r.Type) == Isinter(l.Type) || r.Type.Width >= 1<<16 { if r.Type.IsInterface() == l.Type.IsInterface() || r.Type.Width >= 1<<16 {
r = Nod(aop, r, nil) r = Nod(aop, r, nil)
r.Type = l.Type r.Type = l.Type
r.Typecheck = 1 r.Typecheck = 1
...@@ -641,7 +641,7 @@ OpSwitch: ...@@ -641,7 +641,7 @@ OpSwitch:
if t.Etype != TIDEAL && !Eqtype(l.Type, r.Type) { if t.Etype != TIDEAL && !Eqtype(l.Type, r.Type) {
l, r = defaultlit2(l, r, true) l, r = defaultlit2(l, r, true)
if Isinter(r.Type) == Isinter(l.Type) || aop == 0 { if r.Type.IsInterface() == l.Type.IsInterface() || aop == 0 {
Yyerror("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type) Yyerror("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type)
n.Type = nil n.Type = nil
return n return n
...@@ -656,13 +656,13 @@ OpSwitch: ...@@ -656,13 +656,13 @@ OpSwitch:
// okfor allows any array == array, map == map, func == func. // okfor allows any array == array, map == map, func == func.
// restrict to slice/map/func == nil and nil == slice/map/func. // restrict to slice/map/func == nil and nil == slice/map/func.
if Isfixedarray(l.Type) && algtype1(l.Type, nil) == ANOEQ { if l.Type.IsArray() && algtype1(l.Type, nil) == ANOEQ {
Yyerror("invalid operation: %v (%v cannot be compared)", n, l.Type) Yyerror("invalid operation: %v (%v cannot be compared)", n, l.Type)
n.Type = nil n.Type = nil
return n return n
} }
if Isslice(l.Type) && !isnil(l) && !isnil(r) { if l.Type.IsSlice() && !isnil(l) && !isnil(r) {
Yyerror("invalid operation: %v (slice can only be compared to nil)", n) Yyerror("invalid operation: %v (slice can only be compared to nil)", n)
n.Type = nil n.Type = nil
return n return n
...@@ -730,7 +730,7 @@ OpSwitch: ...@@ -730,7 +730,7 @@ OpSwitch:
n.Right = l n.Right = l
} else if r.Op == OLITERAL && r.Val().Ctype() == CTNIL { } else if r.Op == OLITERAL && r.Val().Ctype() == CTNIL {
} else // leave alone for back end } else // leave alone for back end
if Isinter(r.Type) == Isinter(l.Type) { if r.Type.IsInterface() == l.Type.IsInterface() {
// TODO(marvin): Fix Node.EType type union. // TODO(marvin): Fix Node.EType type union.
n.Etype = EType(n.Op) n.Etype = EType(n.Op)
n.Op = OCMPIFACE n.Op = OCMPIFACE
...@@ -886,7 +886,7 @@ OpSwitch: ...@@ -886,7 +886,7 @@ OpSwitch:
case isnilinter(t): case isnilinter(t):
Yyerror("%v undefined (type %v is interface with no methods)", n, n.Left.Type) Yyerror("%v undefined (type %v is interface with no methods)", n, n.Left.Type)
case Isptr[t.Etype] && Isinter(t.Elem()): case Isptr[t.Etype] && t.Elem().IsInterface():
// Pointer to interface is almost always a mistake. // Pointer to interface is almost always a mistake.
Yyerror("%v undefined (type %v is pointer to interface, not interface)", n, n.Left.Type) Yyerror("%v undefined (type %v is pointer to interface, not interface)", n, n.Left.Type)
...@@ -930,7 +930,7 @@ OpSwitch: ...@@ -930,7 +930,7 @@ OpSwitch:
n.Type = nil n.Type = nil
return n return n
} }
if !Isinter(t) { if !t.IsInterface() {
Yyerror("invalid type assertion: %v (non-interface type %v on left)", n, t) Yyerror("invalid type assertion: %v (non-interface type %v on left)", n, t)
n.Type = nil n.Type = nil
return n return n
...@@ -993,7 +993,7 @@ OpSwitch: ...@@ -993,7 +993,7 @@ OpSwitch:
} }
why := "string" why := "string"
if t.Etype == TARRAY { if t.Etype == TARRAY {
if Isfixedarray(t) { if t.IsArray() {
why = "array" why = "array"
} else { } else {
why = "slice" why = "slice"
...@@ -1009,7 +1009,7 @@ OpSwitch: ...@@ -1009,7 +1009,7 @@ OpSwitch:
x := n.Right.Val().U.(*Mpint).Int64() x := n.Right.Val().U.(*Mpint).Int64()
if x < 0 { if x < 0 {
Yyerror("invalid %s index %v (index must be non-negative)", why, n.Right) Yyerror("invalid %s index %v (index must be non-negative)", why, n.Right)
} else if Isfixedarray(t) && x >= t.Bound { } else if t.IsArray() && x >= t.Bound {
Yyerror("invalid array index %v (out of bounds for %d-element array)", n.Right, t.Bound) Yyerror("invalid array index %v (out of bounds for %d-element array)", n.Right, t.Bound)
} else if Isconst(n.Left, CTSTR) && x >= int64(len(n.Left.Val().U.(string))) { } else if Isconst(n.Left, CTSTR) && x >= int64(len(n.Left.Val().U.(string))) {
Yyerror("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(n.Left.Val().U.(string))) Yyerror("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(n.Left.Val().U.(string)))
...@@ -1102,7 +1102,7 @@ OpSwitch: ...@@ -1102,7 +1102,7 @@ OpSwitch:
n.Right.Left = indexlit(n.Right.Left) n.Right.Left = indexlit(n.Right.Left)
n.Right.Right = indexlit(n.Right.Right) n.Right.Right = indexlit(n.Right.Right)
l := n.Left l := n.Left
if Isfixedarray(l.Type) { if l.Type.IsArray() {
if !islvalue(n.Left) { if !islvalue(n.Left) {
Yyerror("invalid operation %v (slice of unaddressable value)", n) Yyerror("invalid operation %v (slice of unaddressable value)", n)
n.Type = nil n.Type = nil
...@@ -1124,12 +1124,12 @@ OpSwitch: ...@@ -1124,12 +1124,12 @@ OpSwitch:
if Istype(t, TSTRING) { if Istype(t, TSTRING) {
n.Type = t n.Type = t
n.Op = OSLICESTR n.Op = OSLICESTR
} else if Isptr[t.Etype] && Isfixedarray(t.Elem()) { } else if Isptr[t.Etype] && t.Elem().IsArray() {
tp = t.Elem() tp = t.Elem()
n.Type = typSlice(tp.Elem()) n.Type = typSlice(tp.Elem())
dowidth(n.Type) dowidth(n.Type)
n.Op = OSLICEARR n.Op = OSLICEARR
} else if Isslice(t) { } else if t.IsSlice() {
n.Type = t n.Type = t
} else { } else {
Yyerror("cannot slice %v (type %v)", l, t) Yyerror("cannot slice %v (type %v)", l, t)
...@@ -1164,7 +1164,7 @@ OpSwitch: ...@@ -1164,7 +1164,7 @@ OpSwitch:
n.Right.Right.Left = indexlit(n.Right.Right.Left) n.Right.Right.Left = indexlit(n.Right.Right.Left)
n.Right.Right.Right = indexlit(n.Right.Right.Right) n.Right.Right.Right = indexlit(n.Right.Right.Right)
l := n.Left l := n.Left
if Isfixedarray(l.Type) { if l.Type.IsArray() {
if !islvalue(n.Left) { if !islvalue(n.Left) {
Yyerror("invalid operation %v (slice of unaddressable value)", n) Yyerror("invalid operation %v (slice of unaddressable value)", n)
n.Type = nil n.Type = nil
...@@ -1189,12 +1189,12 @@ OpSwitch: ...@@ -1189,12 +1189,12 @@ OpSwitch:
} }
var tp *Type var tp *Type
if Isptr[t.Etype] && Isfixedarray(t.Elem()) { if Isptr[t.Etype] && t.Elem().IsArray() {
tp = t.Elem() tp = t.Elem()
n.Type = typSlice(tp.Elem()) n.Type = typSlice(tp.Elem())
dowidth(n.Type) dowidth(n.Type)
n.Op = OSLICE3ARR n.Op = OSLICE3ARR
} else if Isslice(t) { } else if t.IsSlice() {
n.Type = t n.Type = t
} else { } else {
Yyerror("cannot slice %v (type %v)", l, t) Yyerror("cannot slice %v (type %v)", l, t)
...@@ -1597,7 +1597,7 @@ OpSwitch: ...@@ -1597,7 +1597,7 @@ OpSwitch:
} }
n.Type = t n.Type = t
if !Isslice(t) { if !t.IsSlice() {
if Isconst(args.First(), CTNIL) { if Isconst(args.First(), CTNIL) {
Yyerror("first argument to append must be typed slice; have untyped nil") Yyerror("first argument to append must be typed slice; have untyped nil")
n.Type = nil n.Type = nil
...@@ -1683,7 +1683,7 @@ OpSwitch: ...@@ -1683,7 +1683,7 @@ OpSwitch:
} }
// copy([]byte, string) // copy([]byte, string)
if Isslice(n.Left.Type) && n.Right.Type.Etype == TSTRING { if n.Left.Type.IsSlice() && n.Right.Type.Etype == TSTRING {
if Eqtype(n.Left.Type.Elem(), bytetype) { if Eqtype(n.Left.Type.Elem(), bytetype) {
break OpSwitch break OpSwitch
} }
...@@ -1692,10 +1692,10 @@ OpSwitch: ...@@ -1692,10 +1692,10 @@ OpSwitch:
return n return n
} }
if !Isslice(n.Left.Type) || !Isslice(n.Right.Type) { if !n.Left.Type.IsSlice() || !n.Right.Type.IsSlice() {
if !Isslice(n.Left.Type) && !Isslice(n.Right.Type) { if !n.Left.Type.IsSlice() && !n.Right.Type.IsSlice() {
Yyerror("arguments to copy must be slices; have %v, %v", Tconv(n.Left.Type, FmtLong), Tconv(n.Right.Type, FmtLong)) Yyerror("arguments to copy must be slices; have %v, %v", Tconv(n.Left.Type, FmtLong), Tconv(n.Right.Type, FmtLong))
} else if !Isslice(n.Left.Type) { } else if !n.Left.Type.IsSlice() {
Yyerror("first argument to copy should be slice; have %v", Tconv(n.Left.Type, FmtLong)) Yyerror("first argument to copy should be slice; have %v", Tconv(n.Left.Type, FmtLong))
} else { } else {
Yyerror("second argument to copy should be slice or string; have %v", Tconv(n.Right.Type, FmtLong)) Yyerror("second argument to copy should be slice or string; have %v", Tconv(n.Right.Type, FmtLong))
...@@ -1783,7 +1783,7 @@ OpSwitch: ...@@ -1783,7 +1783,7 @@ OpSwitch:
return n return n
case TARRAY: case TARRAY:
if !Isslice(t) { if !t.IsSlice() {
Yyerror("cannot make type %v", t) Yyerror("cannot make type %v", t)
n.Type = nil n.Type = nil
return n return n
...@@ -1972,7 +1972,7 @@ OpSwitch: ...@@ -1972,7 +1972,7 @@ OpSwitch:
n.Type = nil n.Type = nil
return n return n
} }
if !Isslice(t) && t.Etype != TSTRING { if !t.IsSlice() && t.Etype != TSTRING {
Fatalf("OSPTR of %v", t) Fatalf("OSPTR of %v", t)
} }
if t.Etype == TSTRING { if t.Etype == TSTRING {
...@@ -2303,7 +2303,7 @@ func implicitstar(n *Node) *Node { ...@@ -2303,7 +2303,7 @@ func implicitstar(n *Node) *Node {
if t == nil { if t == nil {
return n return n
} }
if !Isfixedarray(t) { if !t.IsArray() {
return n return n
} }
n = Nod(OIND, n, nil) n = Nod(OIND, n, nil)
...@@ -3142,7 +3142,7 @@ func typecheckcomplit(n *Node) *Node { ...@@ -3142,7 +3142,7 @@ func typecheckcomplit(n *Node) *Node {
func islvalue(n *Node) bool { func islvalue(n *Node) bool {
switch n.Op { switch n.Op {
case OINDEX: case OINDEX:
if Isfixedarray(n.Left.Type) { if n.Left.Type != nil && n.Left.Type.IsArray() {
return islvalue(n.Left) return islvalue(n.Left)
} }
if n.Left.Type != nil && n.Left.Type.Etype == TSTRING { if n.Left.Type != nil && n.Left.Type.Etype == TSTRING {
......
...@@ -544,7 +544,7 @@ opswitch: ...@@ -544,7 +544,7 @@ opswitch:
if Isptr[t.Etype] { if Isptr[t.Etype] {
t = t.Elem() t = t.Elem()
} }
if Isfixedarray(t) { if t.IsArray() {
safeexpr(n.Left, init) safeexpr(n.Left, init)
Nodconst(n, n.Type, t.Bound) Nodconst(n, n.Type, t.Bound)
n.Typecheck = 1 n.Typecheck = 1
...@@ -1004,18 +1004,18 @@ opswitch: ...@@ -1004,18 +1004,18 @@ opswitch:
var ll []*Node var ll []*Node
if isnilinter(n.Type) { if isnilinter(n.Type) {
if !Isinter(n.Left.Type) { if !n.Left.Type.IsInterface() {
ll = append(ll, typename(n.Left.Type)) ll = append(ll, typename(n.Left.Type))
} }
} else { } else {
if Isinter(n.Left.Type) { if n.Left.Type.IsInterface() {
ll = append(ll, typename(n.Type)) ll = append(ll, typename(n.Type))
} else { } else {
ll = append(ll, itabname(n.Left.Type, n.Type)) ll = append(ll, itabname(n.Left.Type, n.Type))
} }
} }
if Isinter(n.Left.Type) { if n.Left.Type.IsInterface() {
ll = append(ll, n.Left) ll = append(ll, n.Left)
} else { } else {
// regular types are passed by reference to avoid C vararg calls // regular types are passed by reference to avoid C vararg calls
...@@ -1044,7 +1044,7 @@ opswitch: ...@@ -1044,7 +1044,7 @@ opswitch:
} }
fn := syslook(convFuncName(n.Left.Type, n.Type)) fn := syslook(convFuncName(n.Left.Type, n.Type))
if !Isinter(n.Left.Type) { if !n.Left.Type.IsInterface() {
fn = substArgTypes(fn, n.Left.Type, n.Left.Type, n.Type) fn = substArgTypes(fn, n.Left.Type, n.Left.Type, n.Type)
} else { } else {
fn = substArgTypes(fn, n.Left.Type, n.Type) fn = substArgTypes(fn, n.Left.Type, n.Type)
...@@ -1157,7 +1157,7 @@ opswitch: ...@@ -1157,7 +1157,7 @@ opswitch:
if t != nil && Isptr[t.Etype] { if t != nil && Isptr[t.Etype] {
t = t.Elem() t = t.Elem()
} }
if Isfixedarray(t) { if t.IsArray() {
n.Bounded = bounded(r, t.Bound) n.Bounded = bounded(r, t.Bound)
if Debug['m'] != 0 && n.Bounded && !Isconst(n.Right, CTINT) { if Debug['m'] != 0 && n.Bounded && !Isconst(n.Right, CTINT) {
Warn("index bounds check elided") Warn("index bounds check elided")
...@@ -1923,7 +1923,7 @@ func walkprint(nn *Node, init *Nodes) *Node { ...@@ -1923,7 +1923,7 @@ func walkprint(nn *Node, init *Nodes) *Node {
t = n.Type t = n.Type
et = n.Type.Etype et = n.Type.Etype
if Isinter(n.Type) { if n.Type.IsInterface() {
if isnilinter(n.Type) { if isnilinter(n.Type) {
on = syslook("printeface") on = syslook("printeface")
} else { } else {
...@@ -1933,7 +1933,7 @@ func walkprint(nn *Node, init *Nodes) *Node { ...@@ -1933,7 +1933,7 @@ func walkprint(nn *Node, init *Nodes) *Node {
} else if Isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR { } else if Isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR {
on = syslook("printpointer") on = syslook("printpointer")
on = substArgTypes(on, n.Type) // any-1 on = substArgTypes(on, n.Type) // any-1
} else if Isslice(n.Type) { } else if n.Type.IsSlice() {
on = syslook("printslice") on = syslook("printslice")
on = substArgTypes(on, n.Type) // any-1 on = substArgTypes(on, n.Type) // any-1
} else if Isint[et] { } else if Isint[et] {
...@@ -2252,7 +2252,7 @@ func reorder3(all []*Node) []*Node { ...@@ -2252,7 +2252,7 @@ func reorder3(all []*Node) []*Node {
continue continue
} }
if l.Op == OINDEX && Isfixedarray(l.Left.Type) { if l.Op == OINDEX && l.Left.Type.IsArray() {
l.Right = reorder3save(l.Right, all, i, &early) l.Right = reorder3save(l.Right, all, i, &early)
l = l.Left l = l.Left
continue continue
...@@ -2317,7 +2317,7 @@ func outervalue(n *Node) *Node { ...@@ -2317,7 +2317,7 @@ func outervalue(n *Node) *Node {
continue continue
} }
if n.Op == OINDEX && Isfixedarray(n.Left.Type) { if n.Op == OINDEX && n.Left.Type != nil && n.Left.Type.IsArray() {
n = n.Left n = n.Left
continue continue
} }
...@@ -3047,10 +3047,10 @@ func walkcompare(n *Node, init *Nodes) *Node { ...@@ -3047,10 +3047,10 @@ func walkcompare(n *Node, init *Nodes) *Node {
var l *Node var l *Node
var r *Node var r *Node
if Isinter(n.Left.Type) && !Isinter(n.Right.Type) { if n.Left.Type.IsInterface() && !n.Right.Type.IsInterface() {
l = n.Left l = n.Left
r = n.Right r = n.Right
} else if !Isinter(n.Left.Type) && Isinter(n.Right.Type) { } else if !n.Left.Type.IsInterface() && n.Right.Type.IsInterface() {
l = n.Right l = n.Right
r = n.Left r = n.Left
} }
...@@ -3097,7 +3097,7 @@ func walkcompare(n *Node, init *Nodes) *Node { ...@@ -3097,7 +3097,7 @@ func walkcompare(n *Node, init *Nodes) *Node {
return n return n
case TARRAY: case TARRAY:
if Isslice(t) { if t.IsSlice() {
return n return n
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment