mirror of
https://github.com/golang/go
synced 2024-09-18 15:32:18 +00:00
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>
This commit is contained in:
parent
eb751fa40b
commit
829adf5047
|
@ -552,19 +552,6 @@ func methtype(t *types.Type) *types.Type {
|
||||||
return nil
|
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.
|
// 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
|
// Any cyclic type must go through a named type, and if one is
|
||||||
|
|
|
@ -1365,7 +1365,7 @@ OpSwitch:
|
||||||
ok = okforcap[t.Etype]
|
ok = okforcap[t.Etype]
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
yyerror("invalid argument %L for %v", n.Left, n.Op)
|
yyerror("invalid argument %L for %v", l, n.Op)
|
||||||
n.Type = nil
|
n.Type = nil
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
@ -1401,7 +1401,6 @@ OpSwitch:
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Left = typecheck(n.Left, Erv)
|
n.Left = typecheck(n.Left, Erv)
|
||||||
n.Left = defaultlit(n.Left, nil)
|
|
||||||
l := n.Left
|
l := n.Left
|
||||||
t := l.Type
|
t := l.Type
|
||||||
if t == nil {
|
if t == nil {
|
||||||
|
@ -1409,22 +1408,57 @@ OpSwitch:
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
if !t.IsComplex() {
|
if t.Etype != TIDEAL && !t.IsComplex() {
|
||||||
yyerror("invalid argument %L for %v", n.Left, n.Op)
|
yyerror("invalid argument %L for %v", l, n.Op)
|
||||||
n.Type = nil
|
n.Type = nil
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
if Isconst(l, CTCPLX) {
|
|
||||||
r := n
|
// if the argument is a constant, the result is a constant
|
||||||
if n.Op == OREAL {
|
// (any untyped numeric constant can be represented as a
|
||||||
n = nodfltconst(&l.Val().U.(*Mpcplx).Real)
|
// complex number)
|
||||||
} else {
|
if l.Op == OLITERAL {
|
||||||
n = nodfltconst(&l.Val().U.(*Mpcplx).Imag)
|
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
|
break OpSwitch
|
||||||
|
|
||||||
case OCOMPLEX:
|
case OCOMPLEX:
|
||||||
|
|
71
test/fixedbugs/issue11945.go
Normal file
71
test/fixedbugs/issue11945.go
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
// run
|
||||||
|
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// issue 17446
|
||||||
|
const (
|
||||||
|
_ = real(0) // from bug report
|
||||||
|
_ = imag(0) // from bug report
|
||||||
|
|
||||||
|
// if the arguments are untyped, the results must be untyped
|
||||||
|
// (and compatible with types that can represent the values)
|
||||||
|
_ int = real(1)
|
||||||
|
_ int = real('a')
|
||||||
|
_ int = real(2.0)
|
||||||
|
_ int = real(3i)
|
||||||
|
|
||||||
|
_ float32 = real(1)
|
||||||
|
_ float32 = real('a')
|
||||||
|
_ float32 = real(2.1)
|
||||||
|
_ float32 = real(3.2i)
|
||||||
|
|
||||||
|
_ float64 = real(1)
|
||||||
|
_ float64 = real('a')
|
||||||
|
_ float64 = real(2.1)
|
||||||
|
_ float64 = real(3.2i)
|
||||||
|
|
||||||
|
_ int = imag(1)
|
||||||
|
_ int = imag('a')
|
||||||
|
_ int = imag(2.1 + 3i)
|
||||||
|
_ int = imag(3i)
|
||||||
|
|
||||||
|
_ float32 = imag(1)
|
||||||
|
_ float32 = imag('a')
|
||||||
|
_ float32 = imag(2.1 + 3.1i)
|
||||||
|
_ float32 = imag(3i)
|
||||||
|
|
||||||
|
_ float64 = imag(1)
|
||||||
|
_ float64 = imag('a')
|
||||||
|
_ float64 = imag(2.1 + 3.1i)
|
||||||
|
_ float64 = imag(3i)
|
||||||
|
)
|
||||||
|
|
||||||
|
var tests = []struct {
|
||||||
|
code string
|
||||||
|
got, want interface{}
|
||||||
|
}{
|
||||||
|
{"real(1)", real(1), 1.0},
|
||||||
|
{"real('a')", real('a'), float64('a')},
|
||||||
|
{"real(2.0)", real(2.0), 2.0},
|
||||||
|
{"real(3.2i)", real(3.2i), 0.0},
|
||||||
|
|
||||||
|
{"imag(1)", imag(1), 0.0},
|
||||||
|
{"imag('a')", imag('a'), 0.0},
|
||||||
|
{"imag(2.1 + 3.1i)", imag(2.1 + 3.1i), 3.1},
|
||||||
|
{"imag(3i)", imag(3i), 3.0},
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// verify compile-time evaluated constant expressions
|
||||||
|
for _, test := range tests {
|
||||||
|
if test.got != test.want {
|
||||||
|
panic(fmt.Sprintf("%s: %v (%T) != %v (%T)", test.code, test.got, test.got, test.want, test.want))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue