return ft
}
+// initLimitForNewValue initializes the limits for newly created values,
+// possibly needing to expand the limits slice. Currently used by
+// simplifyBlock when certain provably constant results are folded.
+func (ft *factsTable) initLimitForNewValue(v *Value) {
+ if int(v.ID) >= len(ft.limits) {
+ f := v.Block.Func
+ n := f.NumValues()
+ if cap(ft.limits) >= n {
+ ft.limits = ft.limits[:n]
+ } else {
+ old := ft.limits
+ ft.limits = f.Cache.allocLimitSlice(n)
+ copy(ft.limits, old)
+ f.Cache.freeLimitSlice(old)
+ }
+ }
+ ft.limits[v.ID] = initLimit(v)
+}
+
// signedMin records the fact that we know v is at least
// min in the signed domain.
func (ft *factsTable) signedMin(v *Value, min int64) bool {
continue
}
v.SetArg(i, c)
+ ft.initLimitForNewValue(c)
if b.Func.pass.debug > 1 {
b.Func.Warnl(v.Pos, "Proved %v's arg %d (%v) is constant %d", v, i, arg, constValue)
}
--- /dev/null
+// run
+
+// Copyright 2024 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 (
+ "reflect"
+)
+
+func main() {
+ pi := new(interface{})
+ v := reflect.ValueOf(pi).Elem()
+ if v.Kind() != reflect.Interface {
+ panic(0)
+ }
+ if (v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface) && v.IsNil() {
+ return
+ }
+ panic(1)
+}