]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: fix missing init nodes for len(string([]byte)) optimization
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Sat, 5 Aug 2023 15:51:49 +0000 (22:51 +0700)
committerGopher Robot <gobot@golang.org>
Mon, 7 Aug 2023 03:12:29 +0000 (03:12 +0000)
CL 497276 added optimization for len(string([]byte)) by avoiding call to
slicebytetostring. However, the bytes to string expression may contain
init nodes, which need to be preserved. Otherwise, it would make the
liveness analysis confusing about the lifetime of temporary variables
created by init nodes.

Fixes #61778

Change-Id: I6d1280a7d61bcc75f11132af41bda086f084ab54
Reviewed-on: https://go-review.googlesource.com/c/go/+/516375
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/walk/builtin.go
test/fixedbugs/issue61778.go [new file with mode: 0644]

index 786c31313c4172f6bd4424c120deb6aa93f36bed..0bb501825071df58476eaa3d2d47949ea8892d74 100644 (file)
@@ -255,7 +255,10 @@ func walkLenCap(n *ir.UnaryExpr, init *ir.Nodes) ir.Node {
                return mkcall("countrunes", n.Type(), init, typecheck.Conv(n.X.(*ir.ConvExpr).X, types.Types[types.TSTRING]))
        }
        if isByteCount(n) {
-               _, len := backingArrayPtrLen(cheapExpr(n.X.(*ir.ConvExpr).X, init))
+               conv := n.X.(*ir.ConvExpr)
+               walkStmtList(conv.Init())
+               init.Append(ir.TakeInit(conv)...)
+               _, len := backingArrayPtrLen(cheapExpr(conv.X, init))
                return len
        }
 
diff --git a/test/fixedbugs/issue61778.go b/test/fixedbugs/issue61778.go
new file mode 100644 (file)
index 0000000..5055c9e
--- /dev/null
@@ -0,0 +1,13 @@
+// compile
+
+// Copyright 2023 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
+
+func f(s []byte) {
+       switch "" {
+       case string(append(s, 'a')):
+       }
+}