Skip to content

Go: migrate control flow graph to shared CFG library#21614

Draft
Copilot wants to merge 6 commits intomainfrom
copilot/vscode-mndb17m3-9fpv
Draft

Go: migrate control flow graph to shared CFG library#21614
Copilot wants to merge 6 commits intomainfrom
copilot/vscode-mndb17m3-9fpv

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 30, 2026

Adopts the shared codeql/controlflow library for Go's CFG implementation, replacing the bespoke ControlFlowGraphImpl.qll (2133 lines) with a shared-library instantiation.

Core architecture changes

  • ControlFlowGraphShared.qll (new): Instantiates CfgLib::Make0/Make1/Make2 with Go-specific Ast and Input modules. Wraps everything in GoCfg to isolate from the old API during transition.
  • ControlFlowGraph.qll: ControlFlow::Node now extends GoCfg::ControlFlowNode instead of the old TControlFlowNode newtype.
  • BasicBlocks.qll: BasicBlock aliased to GoCfg::Cfg::BasicBlock.
  • IR.qll: All 30+ instruction classes rewritten to identify themselves via isAdditional/isIn/isBefore/isAfter predicates instead of Mk* newtype constructors.
  • Removed ControlFlowGraphImpl.qll: fully superseded.

Function prologue/epilogue routing

Changed callableGetBody(c) = c (instead of c.getBody()) so the shared library routes Entry(fd) → Before(fd), allowing funcDefStep to insert prologue and epilogue nodes:

  • Prologue: Before(fd)arg:iparam-init:i (per parameter) → result-zero-init:jresult-init:j (per result var) → Before(body)
  • Epilogue: After(body)result-read:j (per result var) → After(fd)NormalExit

This makes InitParameterInstruction and related classes reachable in the CFG, which is required for SSA and data flow (e.g., SsaParameterNode via IR::initParamInstruction).

Implicit promoted-field reads

Fixed selectorExprStep to route through implicit-field:i additional nodes for promoted field accesses, making ImplicitFieldReadInstruction reachable. The chain descends from the outermost embedded field (highest index) to the innermost (index 1) before reaching In(sel):

After(base) → implicit-field:N → implicit-field:N-1 → ... → implicit-field:1 → In(sel)

Minor fixes

  • SsaImpl.qll: cast bb.getNode(i) to ControlFlow::Node before calling isEntryNode().
  • Revel.qll: use getBaseInstruction() instead of the removed getBase() on ImplicitFieldReadInstruction.
Original prompt

Continue

[Chronological Review: The conversation began with the user requesting a list of commits merged as part of a specific commit hash (e695477). Following that, the user asked to adopt a new shared CFG library for Go based on those commits. The user then prompted to "Continue to iterate?" multiple times, indicating a desire to progress with the implementation. The user also requested to "Do phase 2 now," suggesting a structured approach to the work. Throughout the conversation, there were indications of changes made to specific files, which required checking the current contents before proceeding with edits.]

[Intent Mapping:

  1. "List commits merged as part of e695477" - User wants to understand changes related to a specific commit.
  2. "Using those commits as a guideline, adopt the new shared CFG library for go." - User aims to implement a new library based on previous changes.
  3. "Continue to iterate?" - User is seeking confirmation to proceed with ongoing work.
  4. "Do phase 2 now" - User indicates a structured approach to the project, moving to the next phase.
  5. "Continue" - User is prompting to keep the workflow moving forward.]

[Technical Inventory:

  • Tools: GitHub CodeQL for code analysis and semantic search for code understanding.
  • Files:
    • IR.qll - Current working file for implementing changes.
    • ControlFlowGraph.qll and ControlFlowGraphShared.qll - Files mentioned as having recent edits that need to be checked before further modifications.]

[Code Archaeology:

  • The user has been working on the IR.qll file, which is part of the Go control flow library. The user has also referenced changes in ControlFlowGraph.qll and ControlFlowGraphShared.qll, indicating ongoing modifications in these files.]

[Progress Assessment:

  • Completed Tasks: User has successfully identified the need to adopt a new CFG library and has made edits to relevant files.
  • Partially Complete Work: The user is in the process of implementing changes based on the commits and is iterating through the implementation phases.]

[Context Validation: All critical information for continuation is captured, including the need to check file contents before making edits and the structured approach to the project.]

[Recent Commands Analysis:

  • Last Agent Commands: The user repeatedly requested to "Continue" and "Continue to iterate?" indicating a desire to keep progressing with the implementation.
  • Tool Results Summary: No specific tool results were returned in the recent commands, but the user has been actively engaged in modifying files and seeking to implement changes.
  • Pre-Summary State: The agent was actively working on the IR.qll file and responding to user prompts to continue the workflow.
  • Operation Context: The commands executed were directly related to the user's goal of adopting a new CFG library and iterating through the implementation process.]
1. Conversation Overview: - Primary Objectives: - "List commits merged as part of e695477" - Understanding changes related to a specific commit. - "Using those commits as a guideline, adopt the new shared CFG library for go." - Implementing a new library based on previous changes. - "Continue to iterate?" - Seeking confirmation to proceed with ongoing work. - "Do phase 2 now" - Moving to the next phase of the project. - Session Context: The conversation has focused on implementing changes to the Go control flow library, with multiple requests to continue iterating on the work. - User Intent Evolution: The user has consistently sought to progress through the implementation phases, indicating a structured approach to the project.
  1. Technical Foundation:
  • GitHub CodeQL: A tool for code analysis being used to facilitate the implementation of changes.
  • Files:
    • IR.qll: The current working file for implementing changes.
    • ControlFlowGraph.qll and ControlFlowGraphShared.qll: Files mentioned as having recent edits that need to be checked.
  1. Codebase Status:
  • IR.qll:
    • Purpose: Central file for implementing the new CFG library.
    • Current State: User is actively working on this file.
    • Key Code Segments: Specific functions or classes were not detailed in the conversation.
    • Dependencies: Relates to the overall control flow implementation in Go.
  • ControlFlowGraph.qll and ControlFlowGraphShared.qll:
    • Purpose: Supporting files for the control flow library.
    • Current State: Recent edits made, requiring review before further changes.
  1. Problem Resolution:
  • Issues Encountered: Need to check file contents before making edits due to recent changes.
  • Solutions Implemented: User has been iterating through the implementation process.
  • Debugging Context: No specific debugging issues were mentioned, but the user is cautious about recent changes.
  • Lessons Learned: Importance of reviewing file changes before proceeding with edits.
  1. Progress Tracking:
  • Completed Tasks: User has identified the need for ...

Created from VS Code.

owen-mc added 4 commits March 30, 2026 13:29
…show you the current state of the file:

Read ControlFlowGraphShared.qll, lines 1 to 50

The file compiles successfully. Here's a summary of what was implemented:

ControlFlowGraphShared.qll — Shared CFG library instantiation for Go, wrapped in the GoCfg module to coexist with the existing CFG during transition. Key design decisions:

Ast module (implements AstSig):

Callable = FuncDef with a body
IfStmt — only For if-statements without init (those with init use custom steps)
LoopStmt — uses characteristic predicate pattern (not direct extension) to avoid return type conflicts with BlockStmt
Empty classes for: WhileStmt, DoStmt, ForStmt, ForeachStmt, ThrowStmt, TryStmt, CatchClause, Switch, Case, ConditionalExpr, NullCoalescingExpr (Go doesn't have these constructs)
LogicalAndExpr = LandExpr, LogicalOrExpr = LorExpr, LogicalNotExpr = NotExpr
BooleanLiteral maps to true/false identifiers
skipCfg filters out type expressions, non-rvalue references, parenthesized expressions, etc.
Input module (implements InputSig1 + InputSig2):

Labels: Go statement labels + fallthrough
Custom steps for: if-with-init, for loops, range loops, expression/type switch, case clauses, select statements, defer, go statements
Abrupt completions: panic via calls/div/deref/type-assert/index/conversion, fallthrough, goto
End abrupt completions: labeled statements catch breaks, goto targets
Remaining work (todos 4-6): The GoCfg module is self-contained and doesn't yet replace the existing CFG. Integration with BasicBlocks.qll, IR.qll, and the public ControlFlowGraph.qll API is the next phase — which is a larger effort requiring updates to DataFlow and all downstream consumers.
…red into Go:

Created ControlFlowGraphShared.qll — contains the full GoCfg module with:

Ast module implementing AstSig<Location> — maps Go's AST types to the shared interface, with empty types for constructs Go doesn't have (while/do/try/catch/throw/ternary/null-coalescing)
Input module implementing InputSig1 + InputSig2 — labels, conditional contexts, custom step() predicates for if-with-init, for/range loops, expression/type switches, case clauses, select, defer, and go statements; abrupt completions for panics, fallthrough, and goto
Make0/Make1/Make2 wiring and import Public
Modified ControlFlowGraph.qll — added import of the shared library and re-exports it as module SharedCfg = GoCfg, making shared types accessible as SharedCfg::ControlFlowNode, SharedCfg::ControlFlow::EntryNode, SharedCfg::BasicBlock, etc.

No breakage — all 90 src queries and library files compile cleanly.
Phase 2 progress — shared CFG library fully instantiated with IR support:

ControlFlowGraphShared.qll (1290 lines) now contains:

additionalNode entries for all 30+ synthetic IR operations:

Assignment writes (assign:i), compound RHS (compound-rhs), tuple extraction (extract:i)
Zero initialization (zero-init:i), increment/decrement (implicit-one, incdec-rhs)
Return (return), result write/read (result-write:i, result-read:i)
Function prologue (param-init:i, arg:i, result-init:i, result-zero-init:i)
Range next (next), send (send), implicit deref (implicit-deref)
Slice bounds (implicit-low/high/max), case checks (case-check:i)
Type switch variables (type-switch-var), literal init (lit-init, lit-index)
Implicit field selection (implicit-field:i)
step routing for all constructs needing custom flow:

Assignments (with epilogue node sequencing for extract/assign chains)
Increment/decrement (operand → implicit-one → incdec-rhs → In)
Return statements (expressions → extract → result-write → return)
Index/slice/selector expressions (with implicit deref insertion)
Composite literals (pre-order: allocation first, then element init)
Send statements (channel → value → send)
Plus the existing: if-with-init, for/range loops, switch/select, defer, go
What remains for full migration (making shared types primary):

Rewrite ControlFlowGraph.qll: change ControlFlow::Node from TControlFlowNode to GoCfg::ControlFlowNode
Rewrite IR.qll (1598 lines): map all 30+ IR instruction classes to shared CFG nodes via getAstNode()/getIdTag() instead of Mk* types
Update BasicBlocks.qll to use shared library's built-in BasicBlock
Update ~30 downstream files (SSA, DataFlow, security queries) that reference IR::Instruction/ControlFlow::Node
Add function prologue/epilogue step routing (param init, result init, defer LIFO at exit)
Remove ControlFlowGraphImpl.qll
This remaining work is a substantial rewrite (3000+ lines across 35+ files) that would benefit from being done incrementally with test validation at each step. Shall I continue with the IR.qll rewrite next?
Copilot AI changed the title [WIP] Implement adoption of new shared CFG library for Go Go: migrate control flow graph to shared CFG library Mar 30, 2026
Copilot AI requested a review from owen-mc March 30, 2026 15:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants