Skip to content

Commit f4274e6

Browse files
mdempskydmitshur
authored andcommitted
[release-branch.go1.14] cmd/compile: fix constant conversion involving complex types
In CL 187657, I refactored constant conversion logic without realizing that conversions between int/float and complex types are allowed for constants (assuming the constant values are representable by the destination type), but are never allowed for non-constant expressions. This CL expands convertop to take an extra srcConstant parameter to indicate whether the source expression is a constant; and if so, to allow any numeric-to-numeric conversion. (Conversions of values that cannot be represented in the destination type are rejected by evconst.) Fixes #38123. For #38117. Change-Id: Id7077d749a14c8fd910be38da170fa5254819f2b Reviewed-on: https://go-review.googlesource.com/c/go/+/226197 Run-TryBot: Matthew Dempsky <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> (cherry picked from commit 3431428) Reviewed-on: https://go-review.googlesource.com/c/go/+/232719 Run-TryBot: Dmitri Shuralyov <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
1 parent b7eca1c commit f4274e6

File tree

3 files changed

+28
-3
lines changed

3 files changed

+28
-3
lines changed

src/cmd/compile/internal/gc/subr.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ func methtype(t *types.Type) *types.Type {
542542
// Is type src assignment compatible to type dst?
543543
// If so, return op code to use in conversion.
544544
// If not, return 0.
545-
func assignop(src *types.Type, dst *types.Type, why *string) Op {
545+
func assignop(src, dst *types.Type, why *string) Op {
546546
if why != nil {
547547
*why = ""
548548
}
@@ -665,7 +665,8 @@ func assignop(src *types.Type, dst *types.Type, why *string) Op {
665665
// Can we convert a value of type src to a value of type dst?
666666
// If so, return op code to use in conversion (maybe OCONVNOP).
667667
// If not, return 0.
668-
func convertop(src *types.Type, dst *types.Type, why *string) Op {
668+
// srcConstant indicates whether the value of type src is a constant.
669+
func convertop(srcConstant bool, src, dst *types.Type, why *string) Op {
669670
if why != nil {
670671
*why = ""
671672
}
@@ -741,6 +742,13 @@ func convertop(src *types.Type, dst *types.Type, why *string) Op {
741742
return OCONV
742743
}
743744

745+
// Special case for constant conversions: any numeric
746+
// conversion is potentially okay. We'll validate further
747+
// within evconst. See #38117.
748+
if srcConstant && (src.IsInteger() || src.IsFloat() || src.IsComplex()) && (dst.IsInteger() || dst.IsFloat() || dst.IsComplex()) {
749+
return OCONV
750+
}
751+
744752
// 6. src is an integer or has type []byte or []rune
745753
// and dst is a string type.
746754
if src.IsInteger() && dst.IsString() {

src/cmd/compile/internal/gc/typecheck.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1634,7 +1634,7 @@ func typecheck1(n *Node, top int) (res *Node) {
16341634
return n
16351635
}
16361636
var why string
1637-
n.Op = convertop(t, n.Type, &why)
1637+
n.Op = convertop(n.Left.Op == OLITERAL, t, n.Type, &why)
16381638
if n.Op == 0 {
16391639
if !n.Diag() && !n.Type.Broke() && !n.Left.Diag() {
16401640
yyerror("cannot convert %L to type %v%s", n.Left, n.Type, why)

test/fixedbugs/issue38117.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// errorcheck
2+
3+
// Copyright 2020 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
// cmd/compile erroneously rejected conversions of constant values
8+
// between int/float and complex types.
9+
10+
package p
11+
12+
const (
13+
_ = int(complex64(int(0)))
14+
_ = float64(complex128(float64(0)))
15+
16+
_ = int8(complex128(1000)) // ERROR "overflow"
17+
)

0 commit comments

Comments
 (0)