if ft.lens == nil {
ft.lens = map[ID]*Value{}
}
- ft.lens[v.Args[0].ID] = v
+ // Set all len Values for the same slice as equal in the poset.
+ // The poset handles transitive relations, so Values related to
+ // any OpSliceLen for this slice will be correctly related to others.
+ if l, ok := ft.lens[v.Args[0].ID]; ok {
+ ft.update(b, v, l, signed, eq)
+ } else {
+ ft.lens[v.Args[0].ID] = v
+ }
ft.update(b, v, ft.zero, signed, gt|eq)
if v.Args[0].Op == OpSliceMake {
if lensVars == nil {
if ft.caps == nil {
ft.caps = map[ID]*Value{}
}
- ft.caps[v.Args[0].ID] = v
+ // Same as case OpSliceLen above, but for slice cap.
+ if c, ok := ft.caps[v.Args[0].ID]; ok {
+ ft.update(b, v, c, signed, eq)
+ } else {
+ ft.caps[v.Args[0].ID] = v
+ }
ft.update(b, v, ft.zero, signed, gt|eq)
if v.Args[0].Op == OpSliceMake {
if lensVars == nil {
_ = b[i] // ERROR "Proved IsInBounds$"
}
+func trans4(b []byte, x int) {
+ // Issue #42603: slice len/cap transitive relations.
+ switch x {
+ case 0:
+ if len(b) < 20 {
+ return
+ }
+ _ = b[:2] // ERROR "Proved IsSliceInBounds$"
+ case 1:
+ if len(b) < 40 {
+ return
+ }
+ _ = b[:2] // ERROR "Proved IsSliceInBounds$"
+ }
+}
+
// Derived from nat.cmp
func natcmp(x, y []uint) (r int) {
m := len(x)