aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorCuong Manh Le <cuong.manhle.vn@gmail.com>2026-03-30 13:15:38 +0700
committerGopher Robot <gobot@golang.org>2026-03-31 10:58:53 -0700
commit9002bd9fa1a3b500ca570844ea563967268a3878 (patch)
treeefb230d9569af0cfdf1cb58e932d5f7393db631a /src/cmd
parentd9fbe4c90d956f7835224f4de1afcf799e8cc3ed (diff)
downloadgo-9002bd9fa1a3b500ca570844ea563967268a3878.tar.xz
cmd/compile: ensure map/slice clearing expressions are walked
The order pass ensures that initialization operations for clear(expr) are scheduled. However, if 'expr' is a conversion that the walk pass subsequently optimizes away or transforms, the resulting nodes can be left in an un-walked state. These un-walked nodes reach the SSA backend, which does not expect high-level IR, resulting in an ICE. This change ensures the expression is always walked during the transformation of the 'clear' builtin. Fixes #78410 Change-Id: I1997a28af020f39b2d325a58429eff9495048b1f Reviewed-on: https://go-review.googlesource.com/c/go/+/760981 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Junyang Shao <shaojunyang@google.com> Reviewed-by: David Chase <drchase@google.com> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/compile/internal/walk/builtin.go7
-rw-r--r--src/cmd/compile/internal/walk/expr.go2
2 files changed, 5 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/walk/builtin.go b/src/cmd/compile/internal/walk/builtin.go
index 2288df709d..4d056da184 100644
--- a/src/cmd/compile/internal/walk/builtin.go
+++ b/src/cmd/compile/internal/walk/builtin.go
@@ -136,17 +136,18 @@ func walkGrowslice(slice *ir.Name, init *ir.Nodes, oldPtr, newLen, oldCap, num i
}
// walkClear walks an OCLEAR node.
-func walkClear(n *ir.UnaryExpr) ir.Node {
+func walkClear(n *ir.UnaryExpr, init *ir.Nodes) ir.Node {
+ x := walkExpr(n.X, init)
typ := n.X.Type()
switch {
case typ.IsSlice():
- if n := arrayClear(n.X.Pos(), n.X, nil); n != nil {
+ if n := arrayClear(x.Pos(), x, nil); n != nil {
return n
}
// If n == nil, we are clearing an array which takes zero memory, do nothing.
return ir.NewBlockStmt(n.Pos(), nil)
case typ.IsMap():
- return mapClear(n.X, reflectdata.TypePtrAt(n.X.Pos(), n.X.Type()))
+ return mapClear(x, reflectdata.TypePtrAt(x.Pos(), typ))
}
panic("unreachable")
}
diff --git a/src/cmd/compile/internal/walk/expr.go b/src/cmd/compile/internal/walk/expr.go
index 125ffd53b1..1ebf6db7f1 100644
--- a/src/cmd/compile/internal/walk/expr.go
+++ b/src/cmd/compile/internal/walk/expr.go
@@ -293,7 +293,7 @@ func walkExpr1(n ir.Node, init *ir.Nodes) ir.Node {
case ir.OCLEAR:
n := n.(*ir.UnaryExpr)
- return walkClear(n)
+ return walkClear(n, init)
case ir.OCLOSE:
n := n.(*ir.UnaryExpr)