Skip to content

Ruby: Replace CFG with shared implementation - #22158

Open
aschackmull wants to merge 10 commits into
github:mainfrom
aschackmull:ruby/cfg-swap
Open

Ruby: Replace CFG with shared implementation#22158
aschackmull wants to merge 10 commits into
github:mainfrom
aschackmull:ruby/cfg-swap

Conversation

@aschackmull

@aschackmull aschackmull commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

This replaces the Ruby control flow graph with an instantiation of the shared library.

@github-actions github-actions Bot added the Ruby label Jul 10, 2026
Comment thread ruby/ql/lib/codeql/ruby/controlflow/ControlFlowGraph2.qll Fixed
@aschackmull
aschackmull force-pushed the ruby/cfg-swap branch 3 times, most recently from 597c62a to e8c7a76 Compare July 10, 2026 13:02
@aschackmull
aschackmull force-pushed the ruby/cfg-swap branch 3 times, most recently from 10337a2 to 8b0d578 Compare July 30, 2026 12:03
Comment thread ruby/ql/lib/codeql/ruby/controlflow/internal/Guards.qll Fixed
Comment thread ruby/ql/lib/codeql/ruby/controlflow/internal/Guards.qll Fixed
@aschackmull
aschackmull force-pushed the ruby/cfg-swap branch 4 times, most recently from c74162e to 8dcd6e6 Compare August 11, 2026 12:10
Comment on lines +16 to +18
guardNode.isAfterValue(guard.getAstNode(), s) and
s.getValue() = branch and
guardNode.getBasicBlock().dominates(bb)
@aschackmull
aschackmull marked this pull request as ready for review August 11, 2026 12:50
@aschackmull
aschackmull requested a review from a team as a code owner August 11, 2026 12:50
Copilot AI balanced review requested due to automatic review settings August 11, 2026 12:50
@aschackmull aschackmull added the no-change-note-required This PR does not need a change note label Aug 11, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Replaces Ruby’s custom control-flow graph implementation with the shared control-flow library and updates dependent analyses and test baselines.

Changes:

  • Instantiates the shared CFG framework for Ruby and removes bespoke CFG, completion, splitting, and basic-block implementations.
  • Migrates SSA, data-flow, security, framework, and IDE consumers to shared CFG APIs.
  • Refreshes affected expected test results and consistency checks.
Show a summary per file
File Description
ruby/ql/test/library-tests/variables/ssa.expected Updates SSA results for the shared CFG.
ruby/ql/test/library-tests/frameworks/active_record/ActiveRecord.expected Updates Active Record data-flow results.
ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected Updates type-tracking results.
ruby/ql/test/library-tests/dataflow/local/Nodes.expected Updates local data-flow nodes.
ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.ql Uses shared basic-block types.
ruby/ql/test/library-tests/controlflow/graph/Nodes.expected Updates CFG node results.
ruby/ql/test/library-tests/controlflow/graph/Cfg.ql Uses shared CFG test output.
ruby/ql/test/library-tests/controlflow/graph/BasicBlocks.ql Adapts basic-block tests.
ruby/ql/test/library-tests/ast/ValueText.expected Updates CFG-backed value results.
ruby/ql/src/queries/variables/DeadStoreOfLocal.ql Uses enclosing callable scope.
ruby/ql/src/queries/performance/DatabaseQueryInLoop.ql Updates loop scope lookup.
ruby/ql/src/experimental/performance/UseDetect.ql Uses direct control-flow-node lookup.
ruby/ql/lib/ide-contextual-queries/printCfg.ql Migrates CFG visualization APIs.
ruby/ql/lib/codeql/ruby/security/ConditionalBypassCustomizations.qll Adapts edge-dominance checks.
ruby/ql/lib/codeql/ruby/frameworks/Sinatra.qll Updates callable scope lookup.
ruby/ql/lib/codeql/ruby/dataflow/SSA.qll Simplifies phi-node rendering.
ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll Migrates SSA construction to shared CFG blocks.
ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll Migrates internal data-flow CFG usage.
ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll Updates call scope and file lookup.
ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll Removes bespoke CFG splitting.
ruby/ql/lib/codeql/ruby/controlflow/internal/NonReturning.qll Maps non-returning calls to shared successor types.
ruby/ql/lib/codeql/ruby/controlflow/internal/Guards.qll Adapts guard dominance logic.
ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll Removes the previous CFG implementation.
ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll Removes custom completion modeling.
ruby/ql/lib/codeql/ruby/controlflow/ControlFlowGraph.qll Instantiates and configures the shared CFG.
ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll Migrates Ruby CFG node wrappers.
ruby/ql/lib/codeql/ruby/controlflow/BasicBlocks.qll Removes custom basic-block wrappers.
ruby/ql/lib/codeql/ruby/CFG.qll Drops the removed basic-block import.
ruby/ql/lib/codeql/ruby/ast/Statement.qll Exposes shared control-flow-node mappings.
ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll Excludes synthesized assignment operands from CFG construction.
ruby/ql/consistency-queries/DataFlowConsistency.ql Removes split-specific exclusions.
ruby/ql/consistency-queries/CfgConsistency.ql Uses shared CFG consistency checks.

Review details

Tip

Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 34/38 changed files
  • Comments generated: 0
  • Review effort level: Balanced

@aschackmull
aschackmull force-pushed the ruby/cfg-swap branch 2 times, most recently from 99eb18e to 9859c59 Compare August 20, 2026 11:29
@aschackmull aschackmull removed the no-change-note-required This PR does not need a change note label Aug 24, 2026

@hvitved hvitved left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks for doing this. I have a few minor comments.

ControlFlowNode getControlFlowNode() { result.injects(this) }

/** Gets a control-flow node for this statement, if any. */
CfgNodes::AstCfgNode getAControlFlowNode() { result.getAstNode() = this }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should deprecate this predicate.

}

private R::Ast::AstNode adjustedGetChild(R::Ast::AstNode parent, int index) {
exists(R::Ast::WhenClause when | parent = when |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a mild preference for parent = any(R::Ast::WhenClause when | ... (same in other cases below).

or
findpattern.getElement(index) = result
or
index = 1 + max(int i | exists(findpattern.getElement(i))) and

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use count instead as in the ArrayPattern case (not sure if there can be 0 elements)?

Comment on lines +202 to +203
result = c.(R::Ast::Toplevel).getABeginBlock() or
result = c.(R::Ast::Toplevel).getAStmt() or

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps result = callableGetBodyPart(c, _, _) instead?

Comment on lines +550 to +552
n1.isAfterTrue(ce.getCondition()) and not exists(ce.getThen()) and n2.isAfter(ce)
or
n1.isAfterFalse(ce.getCondition()) and not exists(ce.getElse()) and n2.isAfter(ce)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this instead be done in the shared library?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants