[tools] go/{cfg,analysis/passes/{ctrlflow,buildssa}}: noreturn

2 views
Skip to first unread message

Alan Donovan (Gerrit)

unread,
Dec 17, 2025, 1:31:45 PM (8 days ago) Dec 17
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Alan Donovan has uploaded the change for review

Commit message

go/{cfg,analysis/passes/{ctrlflow,buildssa}}: noreturn

This change exposes the hitherto internal APIs for querying
whether a function can never return, and exploiting this
information during SSA CFG construction.

Fixes golang/go#76161
Change-Id: Iabdaf49d68eb85928f59e207bf69c394d4a06842

Change diff

diff --git a/go/analysis/passes/buildssa/buildssa.go b/go/analysis/passes/buildssa/buildssa.go
index 37c878e..017415f 100644
--- a/go/analysis/passes/buildssa/buildssa.go
+++ b/go/analysis/passes/buildssa/buildssa.go
@@ -16,9 +16,7 @@

"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/ctrlflow"
- "golang.org/x/tools/go/analysis/passes/internal/ctrlflowinternal"
"golang.org/x/tools/go/ssa"
- "golang.org/x/tools/internal/ssainternal"
)

var Analyzer = &analysis.Analyzer{
@@ -62,9 +60,7 @@
prog := ssa.NewProgram(pass.Fset, mode)

// Use the result of the ctrlflow analysis to improve the SSA CFG.
- ssainternal.SetNoReturn(prog, func(fn *types.Func) bool {
- return ctrlflowinternal.NoReturn(cfgs, fn)
- })
+ prog.SetNoReturn(cfgs.NoReturn)

// Create SSA packages for direct imports.
for _, p := range pass.Pkg.Imports() {
diff --git a/go/analysis/passes/ctrlflow/ctrlflow.go b/go/analysis/passes/ctrlflow/ctrlflow.go
index b84c8d6..577c1d4 100644
--- a/go/analysis/passes/ctrlflow/ctrlflow.go
+++ b/go/analysis/passes/ctrlflow/ctrlflow.go
@@ -16,11 +16,9 @@

"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
- "golang.org/x/tools/go/analysis/passes/internal/ctrlflowinternal"
"golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/go/cfg"
"golang.org/x/tools/go/types/typeutil"
- "golang.org/x/tools/internal/cfginternal"
"golang.org/x/tools/internal/typesinternal"
)

@@ -51,18 +49,10 @@
pass *analysis.Pass // transient; nil after construction
}

-// TODO(adonovan): add (*CFGs).NoReturn to public API.
-func (c *CFGs) isNoReturn(fn *types.Func) bool {
+func (c *CFGs) NoReturn(fn *types.Func) bool {
return c.noReturn[fn]
}

-func init() {
- // Expose the hidden method to callers in x/tools.
- ctrlflowinternal.NoReturn = func(c any, fn *types.Func) bool {
- return c.(*CFGs).isNoReturn(fn)
- }
-}
-
// CFGs has two maps: funcDecls for named functions and funcLits for
// unnamed ones. Unlike funcLits, the funcDecls map is not keyed by its
// syntax node, *ast.FuncDecl, because callMayReturn needs to do a
@@ -154,7 +144,7 @@
li := funcLits[lit]
if li.cfg == nil {
li.cfg = cfg.New(lit.Body, c.callMayReturn)
- if cfginternal.IsNoReturn(li.cfg) {
+ if li.cfg.NoReturn() {
li.noReturn = true
}
}
@@ -183,7 +173,7 @@
if !known {
if di.decl.Body != nil {
di.cfg = cfg.New(di.decl.Body, c.callMayReturn)
- if cfginternal.IsNoReturn(di.cfg) {
+ if di.cfg.NoReturn() {
noreturn = true
}
}
diff --git a/go/cfg/cfg.go b/go/cfg/cfg.go
index 38aba77..f69912c 100644
--- a/go/cfg/cfg.go
+++ b/go/cfg/cfg.go
@@ -47,8 +47,6 @@
"go/ast"
"go/format"
"go/token"
-
- "golang.org/x/tools/internal/cfginternal"
)

// A CFG represents the control-flow graph of a single function.
@@ -59,6 +57,9 @@
noreturn bool // function body lacks a reachable return statement
}

+// NoReturn reports whether the function has no reachable return.
+func (cfg *CFG) NoReturn() bool { return cfg.noreturn }
+
// A Block represents a basic block: a list of statements and
// expressions that are always evaluated sequentially.
//
@@ -184,14 +185,6 @@
return &CFG{Blocks: b.blocks, noreturn: noreturn}
}

-// isNoReturn reports whether the function has no reachable return.
-// TODO(adonovan): add (*CFG).NoReturn to public API.
-func isNoReturn(_cfg any) bool { return _cfg.(*CFG).noreturn }
-
-func init() {
- cfginternal.IsNoReturn = isNoReturn // expose to ctrlflow analyzer
-}
-
func (b *Block) String() string {
return fmt.Sprintf("block %d (%s)", b.Index, b.comment(nil))
}
diff --git a/go/ssa/create.go b/go/ssa/create.go
index bbf8856..b3e4bef 100644
--- a/go/ssa/create.go
+++ b/go/ssa/create.go
@@ -15,7 +15,6 @@
"os"
"sync"

- "golang.org/x/tools/internal/ssainternal"
"golang.org/x/tools/internal/versions"
)

@@ -314,19 +313,10 @@
return prog.imported[path]
}

-// setNoReturn sets the predicate used by the SSA builder to decide
-// whether a call to the specified named function cannot return,
-// allowing the builder to prune control-flow edges following the
-// call, thus improving the precision of downstream analysis.
-//
-// TODO(adonovan): add (*Program).SetNoReturn to the public API.
-func (prog *Program) setNoReturn(noReturn func(*types.Func) bool) {
+// SetNoReturn sets the predicate used when building the ssa.Program
+// prog that reports whether a given function cannot return.
+// This may be used to prune spurious control flow edges
+// after (e.g.) log.Fatal, improving the precision of analyses.
+func (prog *Program) SetNoReturn(noReturn func(*types.Func) bool) {
prog.noReturn = noReturn
}
-
-func init() {
- // SetNoReturn exposes Program.setNoReturn to the buildssa analyzer.
- ssainternal.SetNoReturn = func(prog any, noReturn func(*types.Func) bool) {
- prog.(*Program).setNoReturn(noReturn)
- }
-}
diff --git a/internal/cfginternal/cfginternal.go b/internal/cfginternal/cfginternal.go
deleted file mode 100644
index a9b6236..0000000
--- a/internal/cfginternal/cfginternal.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2025 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 cfginternal exposes internals of go/cfg.
-// It cannot actually depend on symbols from go/cfg.
-package cfginternal
-
-// IsNoReturn exposes (*cfg.CFG).noReturn to the ctrlflow analyzer.
-// TODO(adonovan): add CFG.NoReturn to the public API.
-//
-// You must link [golang.org/x/tools/go/cfg] into your application for
-// this function to be non-nil.
-var IsNoReturn = func(cfg any) bool {
- panic("golang.org/x/tools/go/cfg not linked into application")
-}
diff --git a/internal/ssainternal/ssainternal.go b/internal/ssainternal/ssainternal.go
deleted file mode 100644
index 686c5d9..0000000
--- a/internal/ssainternal/ssainternal.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2025 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 ssainternal exposes setters for internals of go/ssa.
-// It cannot actually depend on symbols from go/ssa.
-package ssainternal
-
-import "go/types"
-
-// SetNoReturn sets the predicate used when building the ssa.Program
-// prog that reports whether a given function cannot return.
-// This may be used to prune spurious control flow edges
-// after (e.g.) log.Fatal, improving the precision of analyses.
-//
-// You must link [golang.org/x/tools/go/ssa] into your application for
-// this function to be non-nil.
-//
-// TODO(adonovan): add (*ssa.Program).SetNoReturn to the public API.
-var SetNoReturn = func(prog any, noreturn func(*types.Func) bool) {
- panic("golang.org/x/tools/go/ssa not linked into application")
-}

Change information

Files:
  • M go/analysis/passes/buildssa/buildssa.go
  • M go/analysis/passes/ctrlflow/ctrlflow.go
  • M go/cfg/cfg.go
  • M go/ssa/create.go
  • D internal/cfginternal/cfginternal.go
  • D internal/ssainternal/ssainternal.go
Change size: M
Delta: 6 files changed, 12 insertions(+), 81 deletions(-)
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newchange
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: Iabdaf49d68eb85928f59e207bf69c394d4a06842
Gerrit-Change-Number: 730780
Gerrit-PatchSet: 1
Gerrit-Owner: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Alan Donovan (Gerrit)

unread,
Dec 17, 2025, 1:37:54 PM (8 days ago) Dec 17
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Alan Donovan

Alan Donovan uploaded new patchset

Alan Donovan uploaded patch set #2 to this change.
Open in Gerrit

Related details

Attention is currently required from:
  • Alan Donovan
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newpatchset
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: Iabdaf49d68eb85928f59e207bf69c394d4a06842
Gerrit-Change-Number: 730780
Gerrit-PatchSet: 2
Gerrit-Owner: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
Gerrit-Attention: Alan Donovan <adon...@google.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Alan Donovan (Gerrit)

unread,
Dec 17, 2025, 1:39:59 PM (8 days ago) Dec 17
to goph...@pubsubhelper.golang.org, Austin Clements, Go LUCI, golang-co...@googlegroups.com
Attention needed from Austin Clements

Alan Donovan voted Auto-Submit+1

Auto-Submit+1
Open in Gerrit

Related details

Attention is currently required from:
  • Austin Clements
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: Iabdaf49d68eb85928f59e207bf69c394d4a06842
Gerrit-Change-Number: 730780
Gerrit-PatchSet: 2
Gerrit-Owner: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Austin Clements <aus...@google.com>
Gerrit-Attention: Austin Clements <aus...@google.com>
Gerrit-Comment-Date: Wed, 17 Dec 2025 18:39:55 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
unsatisfied_requirement
satisfied_requirement
open
diffy

Austin Clements (Gerrit)

unread,
Dec 23, 2025, 4:55:13 PM (2 days ago) Dec 23
to Alan Donovan, goph...@pubsubhelper.golang.org, Austin Clements, Go LUCI, golang-co...@googlegroups.com
Attention needed from Alan Donovan

Austin Clements voted and added 1 comment

Votes added by Austin Clements

Code-Review+2

1 comment

File go/analysis/passes/ctrlflow/ctrlflow.go
Line 19, Patchset 2 (Parent): "golang.org/x/tools/go/analysis/passes/internal/ctrlflowinternal"
Austin Clements . unresolved

Also delete the ctrlflowinternal package?

Open in Gerrit

Related details

Attention is currently required from:
  • Alan Donovan
Submit Requirements:
  • requirement satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement satisfiedReview-Enforcement
  • requirement satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: Iabdaf49d68eb85928f59e207bf69c394d4a06842
Gerrit-Change-Number: 730780
Gerrit-PatchSet: 2
Gerrit-Owner: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Austin Clements <aus...@google.com>
Gerrit-Attention: Alan Donovan <adon...@google.com>
Gerrit-Comment-Date: Tue, 23 Dec 2025 21:55:08 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
satisfied_requirement
unsatisfied_requirement
open
diffy

Alan Donovan (Gerrit)

unread,
Dec 23, 2025, 8:56:53 PM (2 days ago) Dec 23
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Alan Donovan and Austin Clements

Alan Donovan uploaded new patchset

Alan Donovan uploaded patch set #3 to this change.
Following approvals got outdated and were removed:
  • Code-Review: +2 by Austin Clements
  • TryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
Open in Gerrit

Related details

Attention is currently required from:
  • Alan Donovan
  • Austin Clements
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newpatchset
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: Iabdaf49d68eb85928f59e207bf69c394d4a06842
Gerrit-Change-Number: 730780
Gerrit-PatchSet: 3
Gerrit-Owner: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Austin Clements <aus...@google.com>
Gerrit-Attention: Alan Donovan <adon...@google.com>
Gerrit-Attention: Austin Clements <aus...@google.com>
unsatisfied_requirement
open
diffy

Alan Donovan (Gerrit)

unread,
Dec 23, 2025, 8:57:06 PM (2 days ago) Dec 23
to goph...@pubsubhelper.golang.org, Austin Clements, Go LUCI, golang-co...@googlegroups.com
Attention needed from Austin Clements

Alan Donovan voted and added 1 comment

Votes added by Alan Donovan

Auto-Submit+1

1 comment

File go/analysis/passes/ctrlflow/ctrlflow.go
Austin Clements . resolved

Also delete the ctrlflowinternal package?

Alan Donovan

Oh, good catch. Done.

Open in Gerrit

Related details

Attention is currently required from:
  • Austin Clements
Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement is not satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: tools
    Gerrit-Branch: master
    Gerrit-Change-Id: Iabdaf49d68eb85928f59e207bf69c394d4a06842
    Gerrit-Change-Number: 730780
    Gerrit-PatchSet: 3
    Gerrit-Owner: Alan Donovan <adon...@google.com>
    Gerrit-Reviewer: Alan Donovan <adon...@google.com>
    Gerrit-Reviewer: Austin Clements <aus...@google.com>
    Gerrit-Attention: Austin Clements <aus...@google.com>
    Gerrit-Comment-Date: Wed, 24 Dec 2025 01:57:04 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    Comment-In-Reply-To: Austin Clements <aus...@google.com>
    unsatisfied_requirement
    satisfied_requirement
    open
    diffy
    Reply all
    Reply to author
    Forward
    0 new messages