From 762eda346a9f4062feaa8a9fc0d17d72b11586f0 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Mon, 23 Nov 2020 15:48:37 -0800 Subject: [PATCH] go/types: fix incorrect string(int) conversion (regression) The bug was introduced by https://golang.org/cl/220844. Fixes #42790. Change-Id: I44d619a1a4d3f2aee1c5575d5cfddcc4ba10895f Reviewed-on: https://go-review.googlesource.com/c/go/+/272666 Trust: Robert Griesemer Run-TryBot: Robert Griesemer TryBot-Result: Go Bot Reviewed-by: Matthew Dempsky --- src/go/types/conversions.go | 16 ++++++++-------- test/fixedbugs/issue42790.go | 9 +++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 test/fixedbugs/issue42790.go diff --git a/src/go/types/conversions.go b/src/go/types/conversions.go index 0955391d7b..1cab1cc70f 100644 --- a/src/go/types/conversions.go +++ b/src/go/types/conversions.go @@ -6,7 +6,10 @@ package types -import "go/constant" +import ( + "go/constant" + "unicode" +) // Conversion type-checks the conversion T(x). // The result is in x. @@ -21,14 +24,11 @@ func (check *Checker) conversion(x *operand, T Type) { case representableConst(x.val, check, t, &x.val): ok = true case isInteger(x.typ) && isString(t): - codepoint := int64(-1) - if i, ok := constant.Int64Val(x.val); ok { - codepoint = i + codepoint := unicode.ReplacementChar + if i, ok := constant.Uint64Val(x.val); ok && i <= unicode.MaxRune { + codepoint = rune(i) } - // If codepoint < 0 the absolute value is too large (or unknown) for - // conversion. This is the same as converting any other out-of-range - // value - let string(codepoint) do the work. - x.val = constant.MakeString(string(rune(codepoint))) + x.val = constant.MakeString(string(codepoint)) ok = true } case x.convertibleTo(check, T): diff --git a/test/fixedbugs/issue42790.go b/test/fixedbugs/issue42790.go new file mode 100644 index 0000000000..d83a02247a --- /dev/null +++ b/test/fixedbugs/issue42790.go @@ -0,0 +1,9 @@ +// compile + +// Copyright 2020 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 p + +const _ = -uint(len(string(1<<32)) - len("\uFFFD"))