In b we only need the division by 0 check.
func b(i uint, v []byte) byte {
return v[i%uint(len(v))]
}
Updates #15079.
Change-Id: Ic7491e677dd57cd6ba577efbce576dbb6e023cbd
Reviewed-on: https://go-review.googlesource.com/21502
Run-TryBot: Alexandru Moșoi <alexandru@mosoi.ro>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Ahmed Waheed <oneofone@gmail.com>
--- /dev/null
+package main
+
+import (
+ "fmt"
+ "runtime"
+)
+
+var failed = false
+
+func checkDivByZero(f func()) (divByZero bool) {
+ defer func() {
+ if r := recover(); r != nil {
+ if e, ok := r.(runtime.Error); ok && e.Error() == "runtime error: integer divide by zero" {
+ divByZero = true
+ }
+ }
+ }()
+ f()
+ return false
+}
+
+//go:noinline
+func a(i uint, s []int) int {
+ return s[i%uint(len(s))]
+}
+
+//go:noinline
+func b(i uint, j uint) uint {
+ return i / j
+}
+
+func main() {
+ if got := checkDivByZero(func() { b(7, 0) }); !got {
+ fmt.Printf("expected div by zero for b(7, 0), got no error\n")
+ failed = true
+ }
+ if got := checkDivByZero(func() { b(7, 7) }); got {
+ fmt.Printf("expected no error for b(7, 7), got div by zero\n")
+ failed = true
+ }
+ if got := checkDivByZero(func() { a(4, nil) }); !got {
+ fmt.Printf("expected div by zero for a(4, nil), got no error\n")
+ failed = true
+ }
+
+ if failed {
+ panic("tests failed")
+ }
+}
(IsInBounds (ZeroExt8to64 _) (Const64 [c])) && (1 << 8) <= c -> (ConstBool [1])
(IsInBounds (ZeroExt16to32 _) (Const32 [c])) && (1 << 16) <= c -> (ConstBool [1])
(IsInBounds (ZeroExt16to64 _) (Const64 [c])) && (1 << 16) <= c -> (ConstBool [1])
-
(IsInBounds x x) -> (ConstBool [0])
(IsInBounds (And32 (Const32 [c]) _) (Const32 [d])) && 0 <= c && c < d -> (ConstBool [1])
(IsInBounds (And64 (Const64 [c]) _) (Const64 [d])) && 0 <= c && c < d -> (ConstBool [1])
(IsInBounds (Const32 [c]) (Const32 [d])) -> (ConstBool [b2i(0 <= c && c < d)])
(IsInBounds (Const64 [c]) (Const64 [d])) -> (ConstBool [b2i(0 <= c && c < d)])
+// (Mod64u x y) is always between 0 (inclusive) and y (exclusive).
+(IsInBounds (Mod32u _ y) y) -> (ConstBool [1])
+(IsInBounds (Mod64u _ y) y) -> (ConstBool [1])
+
(IsSliceInBounds x x) -> (ConstBool [1])
(IsSliceInBounds (And32 (Const32 [c]) _) (Const32 [d])) && 0 <= c && c <= d -> (ConstBool [1])
(IsSliceInBounds (And64 (Const64 [c]) _) (Const64 [d])) && 0 <= c && c <= d -> (ConstBool [1])
v.AuxInt = b2i(0 <= c && c < d)
return true
}
+ // match: (IsInBounds (Mod32u _ y) y)
+ // cond:
+ // result: (ConstBool [1])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpMod32u {
+ break
+ }
+ y := v_0.Args[1]
+ if y != v.Args[1] {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = 1
+ return true
+ }
+ // match: (IsInBounds (Mod64u _ y) y)
+ // cond:
+ // result: (ConstBool [1])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpMod64u {
+ break
+ }
+ y := v_0.Args[1]
+ if y != v.Args[1] {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = 1
+ return true
+ }
return false
}
func rewriteValuegeneric_OpIsSliceInBounds(v *Value, config *Config) bool {