if parent.Func.pass.debug > 1 {
parent.Func.Warnl(parent.Pos, "x+d %s w; x:%v %v delta:%v w:%v d:%v", r, x, parent.String(), delta, w.AuxInt, d)
}
+ underflow := true
+ if l, has := ft.limits[x.ID]; has && delta < 0 {
+ if (x.Type.Size() == 8 && l.min >= math.MinInt64-delta) ||
+ (x.Type.Size() == 4 && l.min >= math.MinInt32-delta) {
+ underflow = false
+ }
+ }
+ if delta < 0 && !underflow {
+ // If delta < 0 and x+delta cannot underflow then x > x+delta (that is, x > v)
+ ft.update(parent, x, v, signed, gt)
+ }
if !w.isGenericIntConst() {
// If we know that x+delta > w but w is not constant, we can derive:
- // if delta < 0 and x > MinInt - delta, then x > w (because x+delta cannot underflow)
+ // if delta < 0 and x+delta cannot underflow, then x > w
// This is useful for loops with bounds "len(slice)-K" (delta = -K)
- if l, has := ft.limits[x.ID]; has && delta < 0 {
- if (x.Type.Size() == 8 && l.min >= math.MinInt64-delta) ||
- (x.Type.Size() == 4 && l.min >= math.MinInt32-delta) {
- ft.update(parent, x, w, signed, r)
- }
+ if delta < 0 && !underflow {
+ ft.update(parent, x, w, signed, r)
}
} else {
// With w,delta constants, we want to derive: x+delta > w ⇒ x > w-delta
-// +build amd64
// errorcheck -0 -d=ssa/prove/debug=1
+//go:build amd64
+// +build amd64
+
// Copyright 2016 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.
func unrollUpIncl(a []int) int {
var i, x int
for i = 0; i <= len(a)-2; i += 2 { // ERROR "Induction variable: limits \[0,\?\], increment 2$"
- x += a[i]
+ x += a[i] // ERROR "Proved IsInBounds$"
x += a[i+1]
}
if i == len(a)-1 {
var i, x int
for i = len(a); i >= 2; i -= 2 { // ERROR "Induction variable: limits \[2,\?\], increment 2$"
x += a[i-1] // ERROR "Proved IsInBounds$"
- x += a[i-2]
+ x += a[i-2] // ERROR "Proved IsInBounds$"
}
if i == 1 {
x += a[i-1]
return blk, rem
}
+func issue51622(b []byte) int {
+ if len(b) >= 3 && b[len(b)-3] == '#' { // ERROR "Proved IsInBounds$"
+ return len(b)
+ }
+ return 0
+}
+
//go:noinline
func useInt(a int) {
}