aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2022-08-08 12:31:33 -0700
committerCherry Mui <cherryyz@google.com>2022-09-19 21:52:38 +0000
commitd5a5db3b41e45a1c5ec39a1a8f91d863e9e7770d (patch)
treea26adc2c078ca4ea4c0b6526eecce2f82ec37350
parent31d06b58fa2448c8e98ac78a97cc9a52dc2aa035 (diff)
downloadgo-d5a5db3b41e45a1c5ec39a1a8f91d863e9e7770d.tar.gz
go-d5a5db3b41e45a1c5ec39a1a8f91d863e9e7770d.zip
[release-branch.go1.18] cmd/compile/internal/inline: fix latent CalleeEffects issue
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 #54918. 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/+/429897 Reviewed-by: Michael Knyszek <mknyszek@google.com>
-rw-r--r--src/cmd/compile/internal/inline/inl.go4
-rw-r--r--test/typeparam/issue54911.go21
2 files changed, 23 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/inline/inl.go b/src/cmd/compile/internal/inline/inl.go
index 716a7fbcd9..bc7ec5cf20 100644
--- a/src/cmd/compile/internal/inline/inl.go
+++ b/src/cmd/compile/internal/inline/inl.go
@@ -771,18 +771,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/typeparam/issue54911.go b/test/typeparam/issue54911.go
new file mode 100644
index 0000000000..0df2b99563
--- /dev/null
+++ b/test/typeparam/issue54911.go
@@ -0,0 +1,21 @@
+// compile -G=3
+
+// 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: {}}
+}