]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.19] cmd/compile/internal/inline: fix latent CalleeEffects issue
authorMatthew Dempsky <mdempsky@google.com>
Mon, 8 Aug 2022 19:31:33 +0000 (12:31 -0700)
committerCherry Mui <cherryyz@google.com>
Mon, 19 Sep 2022 21:52:24 +0000 (21:52 +0000)
ir.ClosureExpr implements ir.InitNode, so ir.InitExpr can prepend init
statements to it. However, CalleeEffects wasn't aware of this and
could cause the init statements to get dropped when inlining a call to
a closure.

This isn't an issue today, because we don't create closures with init
statements. But I ran into this within unified IR.

Easy and robust solution: just take advantage that ir.TakeInit can
handle any node.

Fixes #54917.

Change-Id: Ica05fbf6a8c5be4b11927daf84491a1140da5431
Reviewed-on: https://go-review.googlesource.com/c/go/+/422196
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/429896
Reviewed-by: Michael Knyszek <mknyszek@google.com>
src/cmd/compile/internal/inline/inl.go
test/fixedbugs/issue54911.go [new file with mode: 0644]

index 9ef016ab73f0a622fc8adddb86f3c9e7e324a2d8..16b6a62bba9896efd34710e4847dbd01dbf4f52c 100644 (file)
@@ -798,18 +798,18 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
 // CalleeEffects appends any side effects from evaluating callee to init.
 func CalleeEffects(init *ir.Nodes, callee ir.Node) {
        for {
+               init.Append(ir.TakeInit(callee)...)
+
                switch callee.Op() {
                case ir.ONAME, ir.OCLOSURE, ir.OMETHEXPR:
                        return // done
 
                case ir.OCONVNOP:
                        conv := callee.(*ir.ConvExpr)
-                       init.Append(ir.TakeInit(conv)...)
                        callee = conv.X
 
                case ir.OINLCALL:
                        ic := callee.(*ir.InlinedCallExpr)
-                       init.Append(ir.TakeInit(ic)...)
                        init.Append(ic.Body.Take()...)
                        callee = ic.SingleResult()
 
diff --git a/test/fixedbugs/issue54911.go b/test/fixedbugs/issue54911.go
new file mode 100644 (file)
index 0000000..dee24da
--- /dev/null
@@ -0,0 +1,21 @@
+// compile
+
+// Copyright 2022 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
+
+type Set[T comparable] map[T]struct{}
+
+func (s Set[T]) Add() Set[T] {
+       return s
+}
+
+func (s Set[T]) Copy() Set[T] {
+       return Set[T].Add(s)
+}
+
+func main() {
+       _ = Set[int]{42: {}}
+}