1
0
mirror of https://github.com/golang/go synced 2024-11-22 03:54:39 -07:00

cmd/compile: init limit for newly created value in prove pass

Fixes: #70156

Change-Id: I2e5dc2a39a8e54ec5f18c5f9d1644208cffb2e9a
Reviewed-on: https://go-review.googlesource.com/c/go/+/624695
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
Youlin Feng 2024-11-03 12:10:26 +08:00 committed by Gopher Robot
parent 4f092a9f34
commit cb163ff60b
2 changed files with 43 additions and 0 deletions

View File

@ -462,6 +462,25 @@ func newFactsTable(f *Func) *factsTable {
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 {
@ -2269,6 +2288,7 @@ func simplifyBlock(sdom SparseTree, ft *factsTable, b *Block) {
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)
}

View File

@ -0,0 +1,23 @@
// 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)
}