]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: don't run ComputeAddrTaken on imported generic functions
authorDan Scales <danscales@google.com>
Thu, 18 Nov 2021 18:52:35 +0000 (10:52 -0800)
committerDan Scales <danscales@google.com>
Fri, 19 Nov 2021 00:05:59 +0000 (00:05 +0000)
It causes a crash because of the unexpected XDOT operation. It's not
needed, since we will run ComputeAddrTaken() on function instantiations
after stenciling. And it's not always correct, since we may not be able
to distinguish between a array and a slice, if a type is dependent on a
type param.

However, we do need to call ComputeAddrTaken on instantiations created
during inlining, since that is after the main ComputeAddrTaken pass.

Fixes #49659

Change-Id: I0bb610cf11f14e4aa9068f6ca2a012337b069c79
Reviewed-on: https://go-review.googlesource.com/c/go/+/365214
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/ir/node.go
src/cmd/compile/internal/noder/stencil.go
src/cmd/compile/internal/typecheck/func.go
test/typeparam/issue49659.dir/a.go [new file with mode: 0644]
test/typeparam/issue49659.dir/b.go [new file with mode: 0644]
test/typeparam/issue49659.go [new file with mode: 0644]
test/typeparam/issue49659b.go [new file with mode: 0644]

index 8784f9ef994d653c40fb2d374d8efe12bab92d36..4fdee5010b660c1b8cbab3e02b1c6db068ffdd79 100644 (file)
@@ -584,7 +584,7 @@ func OuterValue(n Node) Node {
        for {
                switch nn := n; nn.Op() {
                case OXDOT:
-                       base.FatalfAt(n.Pos(), "OXDOT in walk: %v", n)
+                       base.FatalfAt(n.Pos(), "OXDOT in OuterValue: %v", n)
                case ODOT:
                        nn := nn.(*SelectorExpr)
                        n = nn.X
index 174006ab5ed416f51dafd9a25bec27e0af0e3ce8..004db54c3b4a80dd1995729295d176e21e8fd2fd 100644 (file)
@@ -109,6 +109,13 @@ func (g *genInst) buildInstantiations(preinliningMainScan bool) {
                // main round of inlining)
                for _, fun := range g.newInsts {
                        inline.InlineCalls(fun.(*ir.Func))
+                       // New instantiations created during inlining should run
+                       // ComputeAddrTaken directly, since we are past the main pass
+                       // that did ComputeAddrTaken(). We could instead do this
+                       // incrementally during stenciling (for all instantiations,
+                       // including main ones before inlining), since we have the
+                       // type information.
+                       typecheck.ComputeAddrtaken(fun.(*ir.Func).Body)
                }
        }
        assert(l == len(g.newInsts))
index 7dec65c1d6875fd54f305557bd7cca485e5da9f8..57b15b7a2bc78e615b42e673d842840ff1863941 100644 (file)
@@ -160,7 +160,12 @@ func ImportedBody(fn *ir.Func) {
        IncrementalAddrtaken = false
        defer func() {
                if DirtyAddrtaken {
-                       ComputeAddrtaken(fn.Inl.Body) // compute addrtaken marks once types are available
+                       // We do ComputeAddrTaken on function instantiations, but not
+                       // generic functions (since we may not yet know if x in &x[i]
+                       // is an array or a slice).
+                       if !fn.Type().HasTParam() {
+                               ComputeAddrtaken(fn.Inl.Body) // compute addrtaken marks once types are available
+                       }
                        DirtyAddrtaken = false
                }
                IncrementalAddrtaken = true
diff --git a/test/typeparam/issue49659.dir/a.go b/test/typeparam/issue49659.dir/a.go
new file mode 100644 (file)
index 0000000..718bc0c
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2021 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 a
+
+type A[T any] struct {
+       a int
+}
+
+func (a A[T]) F() {
+       _ = &a.a
+}
diff --git a/test/typeparam/issue49659.dir/b.go b/test/typeparam/issue49659.dir/b.go
new file mode 100644 (file)
index 0000000..1f37153
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2021 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 b
+
+import "a"
+
+type B[T any] struct {
+       v a.A[T]
+}
+
+func (b B[T]) F() {
+       b.v.F()
+}
diff --git a/test/typeparam/issue49659.go b/test/typeparam/issue49659.go
new file mode 100644 (file)
index 0000000..87b4ff4
--- /dev/null
@@ -0,0 +1,7 @@
+// compiledir -G=3
+
+// Copyright 2021 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 ignored
diff --git a/test/typeparam/issue49659b.go b/test/typeparam/issue49659b.go
new file mode 100644 (file)
index 0000000..a9a14af
--- /dev/null
@@ -0,0 +1,28 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 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.
+
+// Testing that AddrTaken logic doesn't cause problems for function instantiations
+
+package main
+
+type A[T interface{ []int | [5]int }] struct {
+       val T
+}
+
+//go:noinline
+func (a A[T]) F() {
+       _ = &a.val[2]
+}
+
+func main() {
+       var x A[[]int]
+       x.val = make([]int, 4)
+       _ = &x.val[3]
+       x.F()
+       var y A[[5]int]
+       _ = &y.val[3]
+       y.F()
+}