diff options
| author | Cuong Manh Le <cuong.manhle.vn@gmail.com> | 2025-12-01 16:54:54 +0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2025-12-02 16:56:58 -0800 |
| commit | 509ddf38689c10643d89c464e8386f53364635e8 (patch) | |
| tree | 4e2ad0516d69e1f4076187accc12a77b4e81aaa7 /src/cmd | |
| parent | 7cab1b1b26e49512a1ae56916ee39a6cc10dab46 (diff) | |
| download | go-509ddf38689c10643d89c464e8386f53364635e8.tar.xz | |
cmd/compile: ensure bloop only kept alive addressable nodes
Fixes #76636
Change-Id: I881f88dbf62a901452c1d77e6ffca651451c7790
Reviewed-on: https://go-review.googlesource.com/c/go/+/725420
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/compile/internal/bloop/bloop.go | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/src/cmd/compile/internal/bloop/bloop.go b/src/cmd/compile/internal/bloop/bloop.go index 761b07abd4..56fe9a424d 100644 --- a/src/cmd/compile/internal/bloop/bloop.go +++ b/src/cmd/compile/internal/bloop/bloop.go @@ -73,6 +73,14 @@ func getNameFromNode(n ir.Node) *ir.Name { return nil } +// getAddressableNameFromNode is like getNameFromNode but returns nil if the node is not addressable. +func getAddressableNameFromNode(n ir.Node) *ir.Name { + if name := getNameFromNode(n); name != nil && ir.IsAddressable(name) { + return name + } + return nil +} + // keepAliveAt returns a statement that is either curNode, or a // block containing curNode followed by a call to runtime.KeepAlive for each // node in ns. These calls ensure that nodes in ns will be live until @@ -94,6 +102,9 @@ func keepAliveAt(ns []ir.Node, curNode ir.Node) ir.Node { if n.Sym().IsBlank() { continue } + if !ir.IsAddressable(n) { + base.FatalfAt(n.Pos(), "keepAliveAt: node %v is not addressable", n) + } arg := ir.NewConvExpr(pos, ir.OCONV, types.Types[types.TUNSAFEPTR], typecheck.NodAddr(n)) if !n.Type().IsInterface() { srcRType0 := reflectdata.TypePtrAt(pos, n.Type()) @@ -129,7 +140,7 @@ func preserveStmt(curFn *ir.Func, stmt ir.Node) (ret ir.Node) { switch n := stmt.(type) { case *ir.AssignStmt: // Peel down struct and slice indexing to get the names - name := getNameFromNode(n.X) + name := getAddressableNameFromNode(n.X) if name != nil { debugName(name, n.Pos()) ret = keepAliveAt([]ir.Node{name}, n) @@ -144,7 +155,7 @@ func preserveStmt(curFn *ir.Func, stmt ir.Node) (ret ir.Node) { case *ir.AssignListStmt: ns := []ir.Node{} for _, lhs := range n.Lhs { - name := getNameFromNode(lhs) + name := getAddressableNameFromNode(lhs) if name != nil { debugName(name, n.Pos()) ns = append(ns, name) @@ -159,7 +170,7 @@ func preserveStmt(curFn *ir.Func, stmt ir.Node) (ret ir.Node) { } ret = keepAliveAt(ns, n) case *ir.AssignOpStmt: - name := getNameFromNode(n.X) + name := getAddressableNameFromNode(n.X) if name != nil { debugName(name, n.Pos()) ret = keepAliveAt([]ir.Node{name}, n) @@ -206,7 +217,7 @@ func preserveStmt(curFn *ir.Func, stmt ir.Node) (ret ir.Node) { argTmps := []ir.Node{} names := []ir.Node{} for i, a := range n.Args { - if name := getNameFromNode(a); name != nil { + if name := getAddressableNameFromNode(a); name != nil { // If they are name, keep them alive directly. debugName(name, n.Pos()) names = append(names, name) @@ -215,7 +226,7 @@ func preserveStmt(curFn *ir.Func, stmt ir.Node) (ret ir.Node) { s := a.(*ir.CompLitExpr) ns := []ir.Node{} for i, elem := range s.List { - if name := getNameFromNode(elem); name != nil { + if name := getAddressableNameFromNode(elem); name != nil { debugName(name, n.Pos()) ns = append(ns, name) } else { |
