]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: remove constant arithmetic overflows during typecheck
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Sat, 4 Feb 2023 05:00:20 +0000 (12:00 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 9 Feb 2023 09:33:47 +0000 (09:33 +0000)
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>
src/cmd/compile/internal/typecheck/const.go
test/fixedbugs/issue58293.go [new file with mode: 0644]

index 26a3753c5fde0b89d57c433e8c5877ad61df3444..d43fa31782d6c6df072a4b96033307a39fb9c887 100644 (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
 // 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 (file)
index 0000000..58d5500
--- /dev/null
@@ -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
+}