]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: init limit for newly created value in prove pass
authorYoulin Feng <fengyoulin@live.com>
Sun, 3 Nov 2024 04:10:26 +0000 (12:10 +0800)
committerGopher Robot <gobot@golang.org>
Tue, 5 Nov 2024 16:55:14 +0000 (16:55 +0000)
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>
src/cmd/compile/internal/ssa/prove.go
test/fixedbugs/issue70156.go [new file with mode: 0644]

index c0ab38139d3bd49443a6f5dbc776e2033bce07be..db91e70499ed7b85a33edc33f8cac0d4b89f9e5b 100644 (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)
                        }
diff --git a/test/fixedbugs/issue70156.go b/test/fixedbugs/issue70156.go
new file mode 100644 (file)
index 0000000..30a732a
--- /dev/null
@@ -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)
+}