Commit d8899aca authored by Robert Griesemer's avatar Robert Griesemer

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/45076Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
parent fcee1e37
...@@ -1341,68 +1341,51 @@ OpSwitch: ...@@ -1341,68 +1341,51 @@ OpSwitch:
break OpSwitch break OpSwitch
case OCAP, OLEN, OREAL, OIMAG: case OCAP, OLEN:
ok |= Erv ok |= Erv
if !onearg(n, "%v", n.Op) { if !onearg(n, "%v", n.Op) {
n.Type = nil n.Type = nil
return n return n
} }
n.Left = typecheck(n.Left, Erv) n.Left = typecheck(n.Left, Erv)
n.Left = defaultlit(n.Left, nil) 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 l := n.Left
t := l.Type t := l.Type
if t == nil { if t == nil {
n.Type = nil n.Type = nil
return n return n
} }
switch n.Op {
case OCAP:
if !okforcap[t.Etype] {
goto badcall1
}
case OLEN:
if !okforlen[t.Etype] {
goto badcall1
}
case OREAL, OIMAG: var ok bool
if !t.IsComplex() { if n.Op == OLEN {
goto badcall1 ok = okforlen[t.Etype]
} } else {
if Isconst(l, CTCPLX) { ok = okforcap[t.Etype]
r := n }
if n.Op == OREAL { if !ok {
n = nodfltconst(&l.Val().U.(*Mpcplx).Real) yyerror("invalid argument %L for %v", n.Left, n.Op)
} else { n.Type = nil
n = nodfltconst(&l.Val().U.(*Mpcplx).Imag) return n
}
n.Orig = r
}
n.Type = types.Types[cplxsubtype(t.Etype)]
break OpSwitch
} }
// might be constant // result might be constant
var res int64 = -1 // valid if >= 0
switch t.Etype { switch t.Etype {
case TSTRING: case TSTRING:
if Isconst(l, CTSTR) { if Isconst(l, CTSTR) {
var r Node res = int64(len(l.Val().U.(string)))
nodconst(&r, types.Types[TINT], int64(len(l.Val().U.(string))))
r.Orig = n
n = &r
} }
case TARRAY: case TARRAY:
if callrecv(l) { // has call or receive if !callrecv(l) {
break res = t.NumElem()
} }
}
if res >= 0 {
var r Node var r Node
nodconst(&r, types.Types[TINT], t.NumElem()) nodconst(&r, types.Types[TINT], res)
r.Orig = n r.Orig = n
n = &r n = &r
} }
...@@ -1410,10 +1393,39 @@ OpSwitch: ...@@ -1410,10 +1393,39 @@ OpSwitch:
n.Type = types.Types[TINT] n.Type = types.Types[TINT]
break OpSwitch break OpSwitch
badcall1: case OREAL, OIMAG:
yyerror("invalid argument %L for %v", n.Left, n.Op) ok |= Erv
n.Type = nil if !onearg(n, "%v", n.Op) {
return n 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: case OCOMPLEX:
ok |= Erv ok |= Erv
......
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