Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
External Go gotos targeting an inner stacked label still fail to connect to their destination.
Review effort: Balanced
Findings: 1
Open (1)
What changed in this PR
Generalizes shared CFG abrupt completions to carry resolved jump targets, enabling precise Go and C# goto handling.
Changes:
- Adds resolved
JumpTargetsupport to the shared CFG. - Implements target resolution for Go and C#.
- Adds Go regression coverage and updates other language integrations.
| File | Description |
|---|---|
shared/controlflow/codeql/controlflow/ControlFlowGraph.qll |
Adds targeted abrupt-completion propagation. |
go/ql/lib/semmle/go/controlflow/ControlFlowGraphImpl.qll |
Resolves Go goto destinations. |
go/ql/test/library-tests/semmle/go/controlflow/GotoTarget/GotoTarget.ql |
Queries goto target reachability. |
go/ql/test/library-tests/semmle/go/controlflow/GotoTarget/GotoTarget.expected |
Records expected test results. |
go/ql/test/library-tests/semmle/go/controlflow/GotoTarget/gotos.go |
Supplies stacked-label test cases. |
csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowGraph.qll |
Resolves label, case, and default gotos. |
java/ql/lib/semmle/code/java/ControlFlowGraph.qll |
Implements the extended shared interface. |
python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll |
Implements the extended shared interface. |
ruby/ql/lib/codeql/ruby/controlflow/ControlFlowGraph.qll |
Implements the extended shared interface. |
unified/ql/lib/codeql/unified/internal/ControlFlowGraph.qll |
Implements the extended shared interface. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
ba548eb to
86ead25
Compare
86ead25 to
832228f
Compare
832228f to
22dea67
Compare
8e98770 to
e7d3ae3
Compare
c08ea98 to
fc044f4
Compare
|
@aschackmull I've updated this PR to implement the approach you outlined in your review of Go: fix CFG for nested labels. Please can you have a look. |
| /** Holds if `n` has `l`, possibly through enclosing labeled statements. */ | ||
| private predicate hasLabel(AstNode n, Input1::Label l) { | ||
| Input1::hasLabel(n, l) | ||
| or | ||
| exists(LabeledStmt labeled | labeled.getStmt() = n and hasLabel(labeled, l)) | ||
| } |
There was a problem hiding this comment.
This predicate is semantically different from Input1::hasLabel, so it should have a different name. Also, it's never needed for nodes, n, for which Input1::hasLabel(n, _) holds so we may use strict enclosure. That means we can simplify using a TC:
| /** Holds if `n` has `l`, possibly through enclosing labeled statements. */ | |
| private predicate hasLabel(AstNode n, Input1::Label l) { | |
| Input1::hasLabel(n, l) | |
| or | |
| exists(LabeledStmt labeled | labeled.getStmt() = n and hasLabel(labeled, l)) | |
| } | |
| /** Holds if `n` is marked with a `LabeledStmt` with label `l`. */ | |
| private predicate hasEnclosingLabel(AstNode n, Input1::Label l) { | |
| exists(LabeledStmt labeled | labeled.getStmt+() = n and Input1::hasLabel(labeled, l)) | |
| } |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Fix nested and self-looping goto targets in the shared CFG by adding labeled statements to the shared AST interface and handling label propagation centrally.
Labels now propagate inward for labeled break/continue and outward through nested labeled statements for goto, avoiding incorrect extra targets. The change updates Go, Java, and C# integrations and adds Go tests for stacked labels, sibling labels, and direct self-loops.