return
}
- // Convert or check untyped arguments.
+ // convert or check untyped arguments
d := 0
if isUntyped(x.typ) {
d |= 1
// 2) if one of them is not constant (possible because
// it contains a shift that is yet untyped), convert
// both of them to float64 since they must have the
- // same type to succeed
+ // same type to succeed (this will result in an error
+ // because shifts of floats are not permitted)
if x.mode == constant_ && y.mode == constant_ {
toFloat := func(x *operand) {
if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 {
} else {
check.convertUntyped(x, Typ[Float64])
check.convertUntyped(&y, Typ[Float64])
+ // x and y should be invalid now, but be conservative
+ // and check below
}
}
if x.mode == invalid || y.mode == invalid {
return
}
- // if both arguments are constant, the result is a constant
+ // if both arguments are constants, the result is a constant
if x.mode == constant_ && y.mode == constant_ {
x.val = constant.BinaryOp(x.val, token.ADD, constant.MakeImag(y.val))
} else {
case _Imag, _Real:
// imag(complexT) floatT
// real(complexT) floatT
+
+ // convert or check untyped argument
+ if isUntyped(x.typ) {
+ if x.mode == constant_ {
+ // an untyped constant number can alway be considered
+ // as a complex constant
+ if isNumeric(x.typ) {
+ x.typ = Typ[UntypedComplex]
+ }
+ } else {
+ // an untyped non-constant argument may appear if
+ // it contains a (yet untyped non-constant) shift
+ // epression: convert it to complex128 which will
+ // result in an error (shift of complex value)
+ check.convertUntyped(x, Typ[Complex128])
+ // x should be invalid now, but be conservative and check
+ if x.mode == invalid {
+ return
+ }
+ }
+ }
+
+ // the argument must be of complex type
if !isComplex(x.typ) {
- check.invalidArg(x.pos(), "%s must be a complex number", x)
+ check.invalidArg(x.pos(), "argument has type %s, expected complex type", x.typ)
return
}
+
+ // if the argument is a constant, the result is a constant
if x.mode == constant_ {
if id == _Real {
x.val = constant.Real(x.val)
} else {
x.mode = value
}
- var k BasicKind
+
+ // determine result type
+ var res BasicKind
switch x.typ.Underlying().(*Basic).kind {
case Complex64:
- k = Float32
+ res = Float32
case Complex128:
- k = Float64
+ res = Float64
case UntypedComplex:
- k = UntypedFloat
+ res = UntypedFloat
default:
unreachable()
}
+ resTyp := Typ[res]
if check.Types != nil && x.mode != constant_ {
- check.recordBuiltinType(call.Fun, makeSig(Typ[k], x.typ))
+ check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
}
- x.typ = Typ[k]
+
+ x.typ = resTyp
case _Make:
// make(T, n)
var c128 complex128
_ = imag() // ERROR not enough arguments
_ = imag(1, 2) // ERROR too many arguments
- _ = imag(10 /* ERROR must be a complex number */)
- _ = imag(2.7182818 /* ERROR must be a complex number */)
- _ = imag("foo" /* ERROR must be a complex number */)
+ _ = imag(10)
+ _ = imag(2.7182818)
+ _ = imag("foo" /* ERROR expected complex */)
+ _ = imag('a')
const _5 = imag(1 + 2i)
assert(_5 == 2)
f32 = _5
f32 = imag(x64)
f64 = imag(x128)
- var s []complex64
- _ = imag(s... /* ERROR invalid use of \.\.\. */ )
+ var a []complex64
+ _ = imag(a... /* ERROR invalid use of \.\.\. */ )
+
+ // if argument is untyped, result is untyped
+ const _ byte = imag(1.2 + 3i)
+ const _ complex128 = imag(1.2 + 3i)
+
+ // lhs constant shift operands are typed as complex128
+ var s uint
+ _ = imag(1 /* ERROR must be integer */ << s)
}
func imag2() {
var c128 complex128
_ = real() // ERROR not enough arguments
_ = real(1, 2) // ERROR too many arguments
- _ = real(10 /* ERROR must be a complex number */)
- _ = real(2.7182818 /* ERROR must be a complex number */)
- _ = real("foo" /* ERROR must be a complex number */)
+ _ = real(10)
+ _ = real(2.7182818)
+ _ = real("foo" /* ERROR expected complex */)
const _5 = real(1 + 2i)
assert(_5 == 1)
f32 = _5
var x128 C128
f32 = imag(x64)
f64 = imag(x128)
-
- var s []complex64
- _ = real(s... /* ERROR invalid use of \.\.\. */ )
_, _ = f32, f64
+
+ var a []complex64
+ _ = real(a... /* ERROR invalid use of \.\.\. */ )
+
+ // if argument is untyped, result is untyped
+ const _ byte = real(1 + 2.3i)
+ const _ complex128 = real(1 + 2.3i)
+
+ // lhs constant shift operands are typed as complex128
+ var s uint
+ _ = real(1 /* ERROR must be integer */ << s)
}
func real2() {