aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/walk/convert.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2022-09-12 13:01:57 -0700
committerMatthew Dempsky <mdempsky@google.com>2022-09-19 18:58:26 +0000
commitceffdc8545c3155b030de9e91d399dc34bd3c678 (patch)
treefb5079fbaef6a3178c80927ea89df3a2a7bc1c4b /src/cmd/compile/internal/walk/convert.go
parent29153be75763b7cbf9395d732f454336e3df0286 (diff)
downloadgo-ceffdc8545c3155b030de9e91d399dc34bd3c678.tar.xz
cmd/compile: implement slice-to-array conversions
The conversion T(x) is implemented as *(*T)(x). Accordingly, runtime panic messages for (*T)(x) are made more general. Fixes #46505. Change-Id: I76317c0878b6a5908299506d392eed50d7ef6523 Reviewed-on: https://go-review.googlesource.com/c/go/+/430415 Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Jenny Rakoczy <jenny@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/walk/convert.go')
-rw-r--r--src/cmd/compile/internal/walk/convert.go18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/walk/convert.go b/src/cmd/compile/internal/walk/convert.go
index 57f28e9800..c67a29fc09 100644
--- a/src/cmd/compile/internal/walk/convert.go
+++ b/src/cmd/compile/internal/walk/convert.go
@@ -503,3 +503,21 @@ func walkCheckPtrArithmetic(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
return cheap
}
+
+// walkSliceToArray walks an OSLICE2ARR expression.
+func walkSliceToArray(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
+ // Replace T(x) with *(*T)(x).
+ conv := typecheck.Expr(ir.NewConvExpr(base.Pos, ir.OCONV, types.NewPtr(n.Type()), n.X)).(*ir.ConvExpr)
+ deref := typecheck.Expr(ir.NewStarExpr(base.Pos, conv)).(*ir.StarExpr)
+
+ // The OSLICE2ARRPTR conversion handles checking the slice length,
+ // so the dereference can't fail.
+ //
+ // However, this is more than just an optimization: if T is a
+ // zero-length array, then x (and thus (*T)(x)) can be nil, but T(x)
+ // should *not* panic. So suppressing the nil check here is
+ // necessary for correctness in that case.
+ deref.SetBounded(true)
+
+ return walkExpr(deref, init)
+}