Uh oh!
There was an error while loading. Please reload this page.
Ruby: Replace CFG with shared implementation - #22158
Conversation
Uh oh!
There was an error while loading. Please reload this page.
597c62a to
e8c7a76Compare10337a2 to
8b0d578CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
c74162e to
8dcd6e6Compare| guardNode.isAfterValue(guard.getAstNode(), s) and | ||
| s.getValue() = branch and | ||
| guardNode.getBasicBlock().dominates(bb) |
There was a problem hiding this comment.
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
99eb18e to
9859c59Compare9859c59 to
879280aCompare
hvitved
left a comment
There was a problem hiding this comment.
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 } |
There was a problem hiding this comment.
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 | |
There was a problem hiding this comment.
I have a mild preference for parent = any(R::Ast::WhenClause when | ... (same in other cases below).
There was a problem hiding this comment.
I tried to see how it looks and it generally becomes longer and more indented, so I'll leave it as-is.
| or | ||
| findpattern.getElement(index) = result | ||
| or | ||
| index = 1 + max(int i | exists(findpattern.getElement(i))) and |
There was a problem hiding this comment.
Use count instead as in the ArrayPattern case (not sure if there can be 0 elements)?
There was a problem hiding this comment.
Yep - that's simpler. I don't think there can be 0 elements, though.
| result = c.(R::Ast::Toplevel).getABeginBlock() or | ||
| result = c.(R::Ast::Toplevel).getAStmt() or |
There was a problem hiding this comment.
Perhaps result = callableGetBodyPart(c, _, _) instead?
There was a problem hiding this comment.
I've factored out the common part.
| 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) |
There was a problem hiding this comment.
Should this instead be done in the shared library?
Rerun has been triggered: 3 restarted 🚀 |
Uh oh!
There was an error while loading. Please reload this page.
This replaces the Ruby control flow graph with an instantiation of the shared library.