]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: do not report division by error during typecheck
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 8 Jun 2023 02:58:22 +0000 (09:58 +0700)
committerGopher Robot <gobot@golang.org>
Thu, 15 Jun 2023 18:41:09 +0000 (18:41 +0000)
types2 have already errored about any spec-required overflows, and
division by zero. CL 469595 unintentionally fixed typecheck not to error
about overflows, but zero division is still be checked during tcArith.
This causes unsafe operations with variable size failed to compile,
instead of raising runtime error.

Fixes #60601

Change-Id: I7bea2821099556835c920713397f7c5d8a4025ac
Reviewed-on: https://go-review.googlesource.com/c/go/+/501735
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/cmd/compile/internal/typecheck/expr.go
test/fixedbugs/issue60601.go [new file with mode: 0644]

index 425724426abb073b39299e04dfdd6203eb01f730..2d25f80473e32f0657b16b1c6860cbed739b81b3 100644 (file)
@@ -184,13 +184,6 @@ func tcArith(n ir.Node, op ir.Op, l, r ir.Node) (ir.Node, ir.Node, *types.Type)
                }
        }
 
-       if (op == ir.ODIV || op == ir.OMOD) && ir.IsConst(r, constant.Int) {
-               if constant.Sign(r.Val()) == 0 {
-                       base.Errorf("division by zero")
-                       return l, r, nil
-               }
-       }
-
        return l, r, t
 }
 
diff --git a/test/fixedbugs/issue60601.go b/test/fixedbugs/issue60601.go
new file mode 100644 (file)
index 0000000..5308989
--- /dev/null
@@ -0,0 +1,50 @@
+// run
+
+// 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 main
+
+import (
+       "strings"
+       "unsafe"
+)
+
+func shift[T any]() int64 {
+       return 1 << unsafe.Sizeof(*new(T))
+}
+
+func div[T any]() uintptr {
+       return 1 / unsafe.Sizeof(*new(T))
+}
+
+func add[T any]() int64 {
+       return 1<<63 - 1 + int64(unsafe.Sizeof(*new(T)))
+}
+
+func main() {
+       shift[[62]byte]()
+       shift[[63]byte]()
+       shift[[64]byte]()
+       shift[[100]byte]()
+       shift[[1e6]byte]()
+
+       add[[1]byte]()
+       shouldPanic("divide by zero", func() { div[[0]byte]() })
+}
+
+func shouldPanic(str string, f func()) {
+       defer func() {
+               err := recover()
+               if err == nil {
+                       panic("did not panic")
+               }
+               s := err.(error).Error()
+               if !strings.Contains(s, str) {
+                       panic("got panic " + s + ", want " + str)
+               }
+       }()
+
+       f()
+}