From: Robert Griesemer Date: Wed, 7 Jun 2017 21:14:20 +0000 (-0700) Subject: cmd/compile: separate code for len, cap from code for real, imag X-Git-Tag: go1.9beta1~84 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=d8899acaf896529a5ab119af3e52ab5ad9488e51;p=gostls13.git cmd/compile: separate code for len, cap from code for real, imag Prep work for issues mentioned below. No semantic or functionality change. For #11945. For #17446. Change-Id: Ia1bb2b87647a6daa47f7863c0eb42cf5e1d35a7c Reviewed-on: https://go-review.googlesource.com/45076 Reviewed-by: Matthew Dempsky --- diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index 04efcc3d82..b3dfe9dc8c 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -1341,68 +1341,51 @@ OpSwitch: break OpSwitch - case OCAP, OLEN, OREAL, OIMAG: + case OCAP, OLEN: ok |= Erv if !onearg(n, "%v", n.Op) { n.Type = nil return n } + n.Left = typecheck(n.Left, Erv) n.Left = defaultlit(n.Left, nil) - if n.Op == OCAP || n.Op == OLEN { - n.Left = implicitstar(n.Left) - } + n.Left = implicitstar(n.Left) l := n.Left t := l.Type if t == nil { n.Type = nil return n } - switch n.Op { - case OCAP: - if !okforcap[t.Etype] { - goto badcall1 - } - - case OLEN: - if !okforlen[t.Etype] { - goto badcall1 - } - case OREAL, OIMAG: - if !t.IsComplex() { - goto badcall1 - } - if Isconst(l, CTCPLX) { - r := n - if n.Op == OREAL { - n = nodfltconst(&l.Val().U.(*Mpcplx).Real) - } else { - n = nodfltconst(&l.Val().U.(*Mpcplx).Imag) - } - n.Orig = r - } - - n.Type = types.Types[cplxsubtype(t.Etype)] - break OpSwitch + var ok bool + if n.Op == OLEN { + ok = okforlen[t.Etype] + } else { + ok = okforcap[t.Etype] + } + if !ok { + yyerror("invalid argument %L for %v", n.Left, n.Op) + n.Type = nil + return n } - // might be constant + // result might be constant + var res int64 = -1 // valid if >= 0 switch t.Etype { case TSTRING: if Isconst(l, CTSTR) { - var r Node - nodconst(&r, types.Types[TINT], int64(len(l.Val().U.(string)))) - r.Orig = n - n = &r + res = int64(len(l.Val().U.(string))) } case TARRAY: - if callrecv(l) { // has call or receive - break + if !callrecv(l) { + res = t.NumElem() } + } + if res >= 0 { var r Node - nodconst(&r, types.Types[TINT], t.NumElem()) + nodconst(&r, types.Types[TINT], res) r.Orig = n n = &r } @@ -1410,10 +1393,39 @@ OpSwitch: n.Type = types.Types[TINT] break OpSwitch - badcall1: - yyerror("invalid argument %L for %v", n.Left, n.Op) - n.Type = nil - return n + case OREAL, OIMAG: + ok |= Erv + if !onearg(n, "%v", n.Op) { + n.Type = nil + return n + } + + n.Left = typecheck(n.Left, Erv) + n.Left = defaultlit(n.Left, nil) + l := n.Left + t := l.Type + if t == nil { + n.Type = nil + return n + } + + if !t.IsComplex() { + yyerror("invalid argument %L for %v", n.Left, n.Op) + n.Type = nil + return n + } + if Isconst(l, CTCPLX) { + r := n + if n.Op == OREAL { + n = nodfltconst(&l.Val().U.(*Mpcplx).Real) + } else { + n = nodfltconst(&l.Val().U.(*Mpcplx).Imag) + } + n.Orig = r + } + + n.Type = types.Types[cplxsubtype(t.Etype)] + break OpSwitch case OCOMPLEX: ok |= Erv