diff options
| author | Matthew Dempsky <mdempsky@google.com> | 2022-09-12 13:01:57 -0700 |
|---|---|---|
| committer | Matthew Dempsky <mdempsky@google.com> | 2022-09-19 18:58:26 +0000 |
| commit | ceffdc8545c3155b030de9e91d399dc34bd3c678 (patch) | |
| tree | fb5079fbaef6a3178c80927ea89df3a2a7bc1c4b /src/cmd/compile/internal/walk/convert.go | |
| parent | 29153be75763b7cbf9395d732f454336e3df0286 (diff) | |
| download | go-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.go | 18 |
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) +} |
