cmd/compile: remove constant arithmetic overflows during typecheck

Since go1.19, these errors are already reported by types2 for any user's
Go code. Compiler generated code, which looks like constant expression
should be evaluated as non-constant semantic, which allows overflows.

Fixes #58293

Change-Id: I6f0049a69bdb0a8d0d7a0db49c7badaa92598ea2
Reviewed-on: https://go-review.googlesource.com/c/go/+/465096
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
This commit is contained in:
Cuong Manh Le 2023-02-04 12:00:20 +07:00
parent 8fb9565832
commit fd208c8850
2 changed files with 15 additions and 34 deletions

View File

@ -34,10 +34,7 @@ func roundFloat(v constant.Value, sz int64) constant.Value {
// truncate float literal fv to 32-bit or 64-bit precision // truncate float literal fv to 32-bit or 64-bit precision
// according to type; return truncated value. // according to type; return truncated value.
func truncfltlit(v constant.Value, t *types.Type) constant.Value { func truncfltlit(v constant.Value, t *types.Type) constant.Value {
if t.IsUntyped() || overflow(v, t) { if t.IsUntyped() {
// If there was overflow, simply continuing would set the
// value to Inf which in turn would lead to spurious follow-on
// errors. Avoid this by returning the existing value.
return v return v
} }
@ -48,10 +45,7 @@ func truncfltlit(v constant.Value, t *types.Type) constant.Value {
// precision, according to type; return truncated value. In case of // precision, according to type; return truncated value. In case of
// overflow, calls Errorf but does not truncate the input value. // overflow, calls Errorf but does not truncate the input value.
func trunccmplxlit(v constant.Value, t *types.Type) constant.Value { func trunccmplxlit(v constant.Value, t *types.Type) constant.Value {
if t.IsUntyped() || overflow(v, t) { if t.IsUntyped() {
// If there was overflow, simply continuing would set the
// value to Inf which in turn would lead to spurious follow-on
// errors. Avoid this by returning the existing value.
return v return v
} }
@ -251,7 +245,6 @@ func convertVal(v constant.Value, t *types.Type, explicit bool) constant.Value {
switch { switch {
case t.IsInteger(): case t.IsInteger():
v = toint(v) v = toint(v)
overflow(v, t)
return v return v
case t.IsFloat(): case t.IsFloat():
v = toflt(v) v = toflt(v)
@ -273,9 +266,6 @@ func tocplx(v constant.Value) constant.Value {
func toflt(v constant.Value) constant.Value { func toflt(v constant.Value) constant.Value {
if v.Kind() == constant.Complex { if v.Kind() == constant.Complex {
if constant.Sign(constant.Imag(v)) != 0 {
base.Errorf("constant %v truncated to real", v)
}
v = constant.Real(v) v = constant.Real(v)
} }
@ -284,9 +274,6 @@ func toflt(v constant.Value) constant.Value {
func toint(v constant.Value) constant.Value { func toint(v constant.Value) constant.Value {
if v.Kind() == constant.Complex { if v.Kind() == constant.Complex {
if constant.Sign(constant.Imag(v)) != 0 {
base.Errorf("constant %v truncated to integer", v)
}
v = constant.Real(v) v = constant.Real(v)
} }
@ -321,25 +308,6 @@ func toint(v constant.Value) constant.Value {
return constant.MakeInt64(1) return constant.MakeInt64(1)
} }
// overflow reports whether constant value v is too large
// to represent with type t, and emits an error message if so.
func overflow(v constant.Value, t *types.Type) bool {
// v has already been converted
// to appropriate form for t.
if t.IsUntyped() {
return false
}
if v.Kind() == constant.Int && constant.BitLen(v) > ir.ConstPrec {
base.Errorf("integer too large")
return true
}
if ir.ConstOverflow(v, t) {
base.Errorf("constant %v overflows %v", types.FmtConst(v, false), t)
return true
}
return false
}
func tostr(v constant.Value) constant.Value { func tostr(v constant.Value) constant.Value {
if v.Kind() == constant.Int { if v.Kind() == constant.Int {
r := unicode.ReplacementChar r := unicode.ReplacementChar

View File

@ -0,0 +1,13 @@
// compile
// Copyright 2023 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
var bar = f(13579)
func f(x uint16) uint16 {
return x>>8 | x<<8
}