]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix unified IR panic when expanding nested inline function
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Fri, 3 Sep 2021 03:49:32 +0000 (10:49 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 9 Sep 2021 04:37:47 +0000 (04:37 +0000)
When reading body of inlining function, which has another inlined
function in the body, the reader still add this inlined function to
todoBodies, which it shouldn't because the inlined function was read
already.

To fix this, introduce new flag to signal that we are done construting
all functions in todoBodies, thus the addBody shouldn't add anything
to todoBodies then.

Updates #48094

Change-Id: I45105dd518f0a7b69c6dcbaf23b957623f271203
Reviewed-on: https://go-review.googlesource.com/c/go/+/347529
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/noder/reader.go
src/cmd/compile/internal/noder/unified.go
test/typeparam/issue48094b.dir/a.go [new file with mode: 0644]
test/typeparam/issue48094b.dir/b.go [new file with mode: 0644]
test/typeparam/issue48094b.go [new file with mode: 0644]

index 57e8476099eb4c0ac17d5cb2bd249c76abb7505b..48f4368113d2c68699ff042b3521ae2f73a4f0cf 100644 (file)
@@ -927,6 +927,11 @@ var bodyReader = map[*ir.Func]pkgReaderIndex{}
 // constructed.
 var todoBodies []*ir.Func
 
+// todoBodiesDone signals that we constructed all function in todoBodies.
+// This is necessary to prevent reader.addBody adds thing to todoBodies
+// when nested inlining happens.
+var todoBodiesDone = false
+
 func (r *reader) addBody(fn *ir.Func) {
        pri := pkgReaderIndex{r.p, r.reloc(relocBody), r.dict}
        bodyReader[fn] = pri
@@ -937,7 +942,7 @@ func (r *reader) addBody(fn *ir.Func) {
                return
        }
 
-       if r.curfn == nil {
+       if r.curfn == nil && !todoBodiesDone {
                todoBodies = append(todoBodies, fn)
                return
        }
index eff2eeaeff57e155e645b5305038c52449bbbcdf..3d4650a01f671381e5f164d4f84dcf6fe0ee56be 100644 (file)
@@ -136,6 +136,7 @@ func unified(noders []*noder) {
                }
        }
        todoBodies = nil
+       todoBodiesDone = true
 
        // Check that nothing snuck past typechecking.
        for _, n := range target.Decls {
diff --git a/test/typeparam/issue48094b.dir/a.go b/test/typeparam/issue48094b.dir/a.go
new file mode 100644 (file)
index 0000000..a113a22
--- /dev/null
@@ -0,0 +1,8 @@
+// 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
+
+func F() { G(0) }
+func G[T any](t T) {}
diff --git a/test/typeparam/issue48094b.dir/b.go b/test/typeparam/issue48094b.dir/b.go
new file mode 100644 (file)
index 0000000..242b34a
--- /dev/null
@@ -0,0 +1,9 @@
+// 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"
+
+func H() { a.F() }
diff --git a/test/typeparam/issue48094b.go b/test/typeparam/issue48094b.go
new file mode 100644 (file)
index 0000000..b83fbd7
--- /dev/null
@@ -0,0 +1,7 @@
+// compiledir
+
+// 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