aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2017-06-07 16:22:21 -0700
committerRobert Griesemer <gri@golang.org>2017-06-08 17:58:26 +0000
commit829adf5047bee5a7cd746e9d6d00d09eb7ac4adb (patch)
treea6d2748763ee5bcb80366cd5f2a364f1380ac70f /src
parenteb751fa40b8b9f8ce2f1fe70cc140ef99fb118a4 (diff)
downloadgo-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.go13
-rw-r--r--src/cmd/compile/internal/gc/typecheck.go58
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: