From cb163ff60b07ce157ebe3571f92d442a137f6757 Mon Sep 17 00:00:00 2001 From: Youlin Feng Date: Sun, 3 Nov 2024 12:10:26 +0800 Subject: [PATCH] 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 Reviewed-by: David Chase Reviewed-by: Mauri de Souza Meneguzzo Reviewed-by: Keith Randall LUCI-TryBot-Result: Go LUCI Reviewed-by: Keith Randall --- src/cmd/compile/internal/ssa/prove.go | 20 ++++++++++++++++++++ test/fixedbugs/issue70156.go | 23 +++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 test/fixedbugs/issue70156.go diff --git a/src/cmd/compile/internal/ssa/prove.go b/src/cmd/compile/internal/ssa/prove.go index c0ab38139d..db91e70499 100644 --- a/src/cmd/compile/internal/ssa/prove.go +++ b/src/cmd/compile/internal/ssa/prove.go @@ -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) } diff --git a/test/fixedbugs/issue70156.go b/test/fixedbugs/issue70156.go new file mode 100644 index 0000000000..30a732a266 --- /dev/null +++ b/test/fixedbugs/issue70156.go @@ -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) +} -- 2.48.1