From 1d6d86bc979dcb302cbf8bdefc5e295f78b49f94 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 22 Oct 2026 10:02:49 +0200 Subject: [PATCH] Unified: Instantiate and expose public SSA api. --- .../lib/codeql/unified/internal/FacadeAst.qll | 7 +++ .../unified/internal/dataflow/LocalSsa.qll | 46 +++++++++++++++++++ unified/ql/lib/unified.qll | 1 + 3 files changed, 54 insertions(+) diff --git a/unified/ql/lib/codeql/unified/internal/FacadeAst.qll b/unified/ql/lib/codeql/unified/internal/FacadeAst.qll index f82683c7f88a..56c34d2ebcca 100644 --- a/unified/ql/lib/codeql/unified/internal/FacadeAst.qll +++ b/unified/ql/lib/codeql/unified/internal/FacadeAst.qll @@ -7,6 +7,7 @@ module; private import AstPlugin private import codeql.files.FileSystem private import codeql.unified.internal.NameBinding as NameBinding +private import codeql.unified.internal.ControlFlowGraph::Public module Unified { private import Ast::Unified as G @@ -124,6 +125,12 @@ module Unified { or result = this.getParent().(Argument).getParent() } + + /** Gets the `ControlFlowNode` corresponding to this expression. */ + ControlFlowNode getControlFlowNode() { result.injects(this) } + + /** Gets the basic block containing this expression. */ + BasicBlock getBasicBlock() { result = this.getControlFlowNode().getBasicBlock() } } class AccessorDeclaration extends G::AccessorDeclaration { diff --git a/unified/ql/lib/codeql/unified/internal/dataflow/LocalSsa.qll b/unified/ql/lib/codeql/unified/internal/dataflow/LocalSsa.qll index 2a92691a6347..5575c0192d52 100644 --- a/unified/ql/lib/codeql/unified/internal/dataflow/LocalSsa.qll +++ b/unified/ql/lib/codeql/unified/internal/dataflow/LocalSsa.qll @@ -37,6 +37,52 @@ module LocalSsaOutput = Make; private import LocalSsaOutput +private module SsaInput implements SsaInputSig { + private import codeql.unified.internal.ExprPositions + + class Expr = U::Expr; + + class Parameter = U::Parameter; + + class VariableWrite instanceof BuilderNode { + private AstNode writeAccess; + + VariableWrite() { this.isLocalVariableWrite(writeAccess, _) } + + Expr asExpr() { hasIncomingValue(writeAccess, result) } + + Expr getValue() { + exists(VariableDeclaration decl | + writeAccess = decl.getPattern() and result = decl.getValue() + ) + or + exists(AssignExpr assignment | + writeAccess = assignment.getTarget() and result = assignment.getValue() + ) + or + writeAccess = result.(CompoundAssignExpr).getTarget() + // TODO: Add case for prefix unary crement operations + } + + predicate isParameterInit(Parameter p) { p.getPattern() = writeAccess } + + string toString() { result = super.toString() } + + Location getLocation() { result = super.getLocation() } + } + + predicate explicitWrite(VariableWrite w, BasicBlock bb, int i, LocalSsaInput::SourceVariable v) { + exists(AstNode repr | + w.(BuilderNode).isLocalVariableWrite(repr, v) and + performsVariableAccess(repr, v, _, bb.getNode(i)) + ) + } +} + +module SsaPublic { + module Ssa = MakeSsa; +} + module LocalSsaDataFlowInput implements DataFlowIntegrationInputSig { class Expr = LocalVariableRefNode; diff --git a/unified/ql/lib/unified.qll b/unified/ql/lib/unified.qll index 7aed5441f0f7..ff3cc986a73e 100644 --- a/unified/ql/lib/unified.qll +++ b/unified/ql/lib/unified.qll @@ -9,4 +9,5 @@ import codeql.unified.internal.AstExtra::Public import codeql.unified.internal.ControlFlowGraph::Public import codeql.unified.internal.NameBinding::Public import codeql.unified.internal.dataflow.DataFlowPublic +import codeql.unified.internal.dataflow.LocalSsa::SsaPublic import codeql.unified.internal.mad.LegacyMaD::Public