diff options
| author | Robert Griesemer <gri@golang.org> | 2017-06-07 16:22:21 -0700 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2017-06-08 17:58:26 +0000 |
| commit | 829adf5047bee5a7cd746e9d6d00d09eb7ac4adb (patch) | |
| tree | a6d2748763ee5bcb80366cd5f2a364f1380ac70f /src | |
| parent | eb751fa40b8b9f8ce2f1fe70cc140ef99fb118a4 (diff) | |
| download | go-829adf5047bee5a7cd746e9d6d00d09eb7ac4adb.tar.xz | |
cmd/compile: fix real/imag for untyped constant arguments
Fixes #11945.
Fixes #17446.
Change-Id: Ic674f6ebc0533ab0f97c650689125994941b72e1
Reviewed-on: https://go-review.googlesource.com/45081
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/gc/subr.go | 13 | ||||
| -rw-r--r-- | src/cmd/compile/internal/gc/typecheck.go | 58 |
2 files changed, 46 insertions, 25 deletions
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go index 365cfad81f..566403bcde 100644 --- a/src/cmd/compile/internal/gc/subr.go +++ b/src/cmd/compile/internal/gc/subr.go @@ -552,19 +552,6 @@ func methtype(t *types.Type) *types.Type { return nil } -func cplxsubtype(et types.EType) types.EType { - switch et { - case TCOMPLEX64: - return TFLOAT32 - - case TCOMPLEX128: - return TFLOAT64 - } - - Fatalf("cplxsubtype: %v\n", et) - return 0 -} - // eqtype reports whether t1 and t2 are identical, following the spec rules. // // Any cyclic type must go through a named type, and if one is diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index b3dfe9dc8c..f21cc8f826 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -1365,7 +1365,7 @@ OpSwitch: ok = okforcap[t.Etype] } if !ok { - yyerror("invalid argument %L for %v", n.Left, n.Op) + yyerror("invalid argument %L for %v", l, n.Op) n.Type = nil return n } @@ -1401,7 +1401,6 @@ OpSwitch: } n.Left = typecheck(n.Left, Erv) - n.Left = defaultlit(n.Left, nil) l := n.Left t := l.Type if t == nil { @@ -1409,22 +1408,57 @@ OpSwitch: return n } - if !t.IsComplex() { - yyerror("invalid argument %L for %v", n.Left, n.Op) + if t.Etype != TIDEAL && !t.IsComplex() { + yyerror("invalid argument %L for %v", l, 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) + + // if the argument is a constant, the result is a constant + // (any untyped numeric constant can be represented as a + // complex number) + if l.Op == OLITERAL { + var re, im *Mpflt + switch consttype(l) { + case CTINT, CTRUNE: + re = newMpflt() + re.SetInt(l.Val().U.(*Mpint)) + // im = 0 + case CTFLT: + re = l.Val().U.(*Mpflt) + // im = 0 + case CTCPLX: + re = &l.Val().U.(*Mpcplx).Real + im = &l.Val().U.(*Mpcplx).Imag + default: + yyerror("invalid argument %L for %v", l, n.Op) + n.Type = nil + return n } - n.Orig = r + if n.Op == OIMAG { + if im == nil { + im = newMpflt() + } + re = im + } + orig := n + n = nodfltconst(re) + n.Orig = orig } - n.Type = types.Types[cplxsubtype(t.Etype)] + // determine result type + et := t.Etype + switch et { + case TIDEAL: + // result is ideal + case TCOMPLEX64: + et = TFLOAT32 + case TCOMPLEX128: + et = TFLOAT64 + default: + Fatalf("unexpected Etype: %v\n", et) + } + n.Type = types.Types[et] break OpSwitch case OCOMPLEX: |
