}
case ir.OADD, ir.OSUB, ir.OMUL, ir.ODIV, ir.OMOD, ir.OOR, ir.OXOR, ir.OAND, ir.OANDNOT:
- n := n.(*ir.BinaryExpr)
- nl, nr := n.X, n.Y
- if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
- rval := nr.Val()
-
- // check for divisor underflow in complex division (see issue 20227)
- if n.Op() == ir.ODIV && n.Type().IsComplex() && constant.Sign(square(constant.Real(rval))) == 0 && constant.Sign(square(constant.Imag(rval))) == 0 {
- base.Errorf("complex division by zero")
- n.SetType(nil)
- return n
- }
- if (n.Op() == ir.ODIV || n.Op() == ir.OMOD) && constant.Sign(rval) == 0 {
- base.Errorf("division by zero")
- n.SetType(nil)
- return n
- }
-
- tok := tokenForOp[n.Op()]
- if n.Op() == ir.ODIV && n.Type().IsInteger() {
- tok = token.QUO_ASSIGN // integer division
- }
- return OrigConst(n, constant.BinaryOp(nl.Val(), tok, rval))
- }
+ return n
case ir.OOROR, ir.OANDAND:
n := n.(*ir.LogicalExpr)
}
case ir.OLSH, ir.ORSH:
- n := n.(*ir.BinaryExpr)
- nl, nr := n.X, n.Y
- if nl.Op() == ir.OLITERAL && nr.Op() == ir.OLITERAL {
- // shiftBound from go/types; "so we can express smallestFloat64" (see issue #44057)
- const shiftBound = 1023 - 1 + 52
- s, ok := constant.Uint64Val(nr.Val())
- if !ok || s > shiftBound {
- base.Errorf("invalid shift count %v", nr)
- n.SetType(nil)
- break
- }
- return OrigConst(n, constant.Shift(toint(nl.Val()), tokenForOp[n.Op()], uint(s)))
- }
+ return n
case ir.OCONV, ir.ORUNESTR:
n := n.(*ir.ConvExpr)
--- /dev/null
+// 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()
+}