From: Cuong Manh Le Date: Sat, 4 Feb 2023 05:00:20 +0000 (+0700) Subject: cmd/compile: remove constant arithmetic overflows during typecheck X-Git-Tag: go1.21rc1~1609 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=fd208c8850cdfe84469d3e4ef9bd55e2e0cece70;p=gostls13.git 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 Auto-Submit: Cuong Manh Le Run-TryBot: Cuong Manh Le Reviewed-by: David Chase TryBot-Result: Gopher Robot Reviewed-by: Tobias Klauser --- diff --git a/src/cmd/compile/internal/typecheck/const.go b/src/cmd/compile/internal/typecheck/const.go index 26a3753c5f..d43fa31782 100644 --- a/src/cmd/compile/internal/typecheck/const.go +++ b/src/cmd/compile/internal/typecheck/const.go @@ -34,10 +34,7 @@ func roundFloat(v constant.Value, sz int64) constant.Value { // truncate float literal fv to 32-bit or 64-bit precision // according to type; return truncated value. func truncfltlit(v constant.Value, t *types.Type) constant.Value { - if t.IsUntyped() || overflow(v, t) { - // 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. + if t.IsUntyped() { 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 // overflow, calls Errorf but does not truncate the input value. func trunccmplxlit(v constant.Value, t *types.Type) constant.Value { - if t.IsUntyped() || overflow(v, t) { - // 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. + if t.IsUntyped() { return v } @@ -251,7 +245,6 @@ func convertVal(v constant.Value, t *types.Type, explicit bool) constant.Value { switch { case t.IsInteger(): v = toint(v) - overflow(v, t) return v case t.IsFloat(): v = toflt(v) @@ -273,9 +266,6 @@ func tocplx(v constant.Value) constant.Value { func toflt(v constant.Value) constant.Value { if v.Kind() == constant.Complex { - if constant.Sign(constant.Imag(v)) != 0 { - base.Errorf("constant %v truncated to real", v) - } v = constant.Real(v) } @@ -284,9 +274,6 @@ func toflt(v constant.Value) constant.Value { func toint(v constant.Value) constant.Value { if v.Kind() == constant.Complex { - if constant.Sign(constant.Imag(v)) != 0 { - base.Errorf("constant %v truncated to integer", v) - } v = constant.Real(v) } @@ -321,25 +308,6 @@ func toint(v constant.Value) constant.Value { 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 { if v.Kind() == constant.Int { r := unicode.ReplacementChar diff --git a/test/fixedbugs/issue58293.go b/test/fixedbugs/issue58293.go new file mode 100644 index 0000000000..58d5500253 --- /dev/null +++ b/test/fixedbugs/issue58293.go @@ -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 +}