aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCuong Manh Le <cuong.manhle.vn@gmail.com>2024-03-07 14:49:30 +0700
committerThan McIntosh <thanm@google.com>2024-03-26 19:24:40 +0000
commite71b0b1fee7df59a99ab6b5192854695d21ff688 (patch)
treecef76a7e2d5291dab3d93fb3f76fbf38249fd950
parent9508eae5d11a518dd650f8964d0201b9fa1760c1 (diff)
downloadgo-e71b0b1fee7df59a99ab6b5192854695d21ff688.tar.gz
go-e71b0b1fee7df59a99ab6b5192854695d21ff688.zip
[release-branch.go1.22] cmd/compile: fix copying SSA-able variables optimization
CL 541715 added an optimization to copy SSA-able variables. When handling m[k] = append(m[k], ...) case, it uses ir.SameSafeExpr to check that m[k] expressions are the same, then doing type assertion to convert the map index to ir.IndexExpr node. However, this assertion is not safe for m[k] expression in append(m[k], ...), since it may be wrapped by ir.OCONVNOP node. Fixing this by un-wrapping any ir.OCONVNOP before doing type assertion. Fixes #66178 Change-Id: I9ff7165ab97bc7f88d0e9b7b31604da19a8ca206 Reviewed-on: https://go-review.googlesource.com/c/go/+/569716 Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/569818 Reviewed-by: David Chase <drchase@google.com>
-rw-r--r--src/cmd/compile/internal/walk/order.go7
-rw-r--r--test/fixedbugs/issue66096.go17
2 files changed, 23 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/walk/order.go b/src/cmd/compile/internal/walk/order.go
index 179fbdb99e..de180a4a8d 100644
--- a/src/cmd/compile/internal/walk/order.go
+++ b/src/cmd/compile/internal/walk/order.go
@@ -643,7 +643,12 @@ func (o *orderState) stmt(n ir.Node) {
indexLHS.Index = o.cheapExpr(indexLHS.Index)
call := n.Y.(*ir.CallExpr)
- indexRHS := call.Args[0].(*ir.IndexExpr)
+ arg0 := call.Args[0]
+ // ir.SameSafeExpr skips OCONVNOPs, so we must do the same here (#66096).
+ for arg0.Op() == ir.OCONVNOP {
+ arg0 = arg0.(*ir.ConvExpr).X
+ }
+ indexRHS := arg0.(*ir.IndexExpr)
indexRHS.X = indexLHS.X
indexRHS.Index = indexLHS.Index
diff --git a/test/fixedbugs/issue66096.go b/test/fixedbugs/issue66096.go
new file mode 100644
index 0000000000..f8621a18b4
--- /dev/null
+++ b/test/fixedbugs/issue66096.go
@@ -0,0 +1,17 @@
+// compile
+
+// 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 p
+
+type Message struct {
+ Header map[string][]string
+}
+
+func f() {
+ m := Message{Header: map[string][]string{}}
+ m.Header[""] = append([]string(m.Header[""]), "")
+ _ = m
+}