mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
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:
parent
8fb9565832
commit
fd208c8850
@ -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
|
||||||
|
13
test/fixedbugs/issue58293.go
Normal file
13
test/fixedbugs/issue58293.go
Normal 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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user