Conversation
e9da755 to
a916e8b
Compare
0f11ca1 to
032b47b
Compare
A parameter with only one name has that name as its internal and external parameter name.
The previous commit resulted in data-flow consistency errors due to having local flow into a post-update node (for good reason). We now skip over the synthetic read node in use-use flow, so the use-use flow is not seen as a mutation of a variable.
This changes the type from Expr -> AstNode and renames the column. This should just be an arbitrary representative for the access; it does not have to be an Expr.
Note that some of them are failing because 'self.store()' is not resolved by static name binding.
This should be taken from the CFG node instead of the AST node
This fixes a data flow consistency error due to ArgumentNodes for constructor patterns missing their PostUpdateNode.
032b47b to
832dfb4
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Call flow currently misses implicit returns, trailing closures, variadics, and high-arity calls, while diagnostics miscount excluded calls.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 3
Open (7)
Restrict candidates to DataFlowCall expressions · New Handle implicit returns in single-expression functions · New Derive positional domain from extracted arguments and parameters · New Fix grammar in class description · New Fix article and conjunction in class description · New Correct “arbitary” typo · New Replace “one or most” with “one or more” · New
What changed in this PR
Adds static-call interprocedural data flow to the unified analysis.
Changes:
- Models arguments, parameters, returns, receivers, and post-call updates.
- Adds call-graph diagnostics and quality metrics.
- Normalizes Swift parameter labels and expands data-flow tests.
| File | Description |
|---|---|
unified/ql/test/library-tests/dataflow/test.swift |
Updates baseline data-flow tests. |
unified/ql/test/library-tests/dataflow/test.expected |
Regenerated data-flow expectations. |
unified/ql/test/library-tests/dataflow/implicit-self.swift |
Tests implicit receiver flow. |
unified/ql/test/library-tests/dataflow/calls.swift |
Adds interprocedural call tests. |
unified/ql/test/library-tests/BasicTest/test.expected |
Updates generated identifier expectations. |
unified/ql/src/diagnostic/ExtractorInformation.ql |
Reports call-graph statistics. |
unified/ql/src/diagnostic/CallGraph.ql |
Adds call-graph diagnostics. |
unified/ql/lib/codeql/unified/internal/LocalNameBinding.qll |
Exposes implicit receiver variables. |
unified/ql/lib/codeql/unified/internal/FacadeAst.qll |
Adds argument and parameter positions. |
unified/ql/lib/codeql/unified/internal/dataflow/ParameterPositions.qll |
Defines call-position matching. |
unified/ql/lib/codeql/unified/internal/dataflow/LocalSsa.qll |
Handles synthetic post-update reads. |
unified/ql/lib/codeql/unified/internal/dataflow/DataFlowNode.qll |
Adds receiver and control-flow nodes. |
unified/ql/lib/codeql/unified/internal/dataflow/DataFlowInstantiation.qll |
Connects interprocedural nodes. |
unified/ql/lib/codeql/unified/internal/dataflow/DataFlowGraph.qll |
Adds receiver-flow edges. |
unified/ql/lib/codeql/unified/internal/dataflow/DataFlowCallable.qll |
Models callable entities. |
unified/ql/lib/codeql/unified/internal/dataflow/DataFlowCall.qll |
Models explicit call sites. |
unified/ql/lib/codeql/unified/internal/dataflow/CallGraph.qll |
Resolves static call targets. |
unified/ql/lib/codeql/unified/internal/dataflow/AllDataFlow.qll |
Re-exports new data-flow modules. |
unified/ql/lib/codeql/unified/internal/AnalysisQuality.qll |
Adds call-graph quality metrics. |
unified/ql/consistency-queries/DataFlowConsistency.ql |
Excludes unreachable argument nodes. |
unified/extractor/tests/corpus/swift/types/class-with-initializer.output |
Regenerated initializer AST output. |
unified/extractor/tests/corpus/swift/functions/function-with-default-parameter-value.output |
Regenerated parameter AST output. |
unified/extractor/src/languages/swift/swift.rs |
Duplicates single Swift parameter names as labels. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| class ReturnNode extends Node { | ||
| ReturnNode() { none() } // TODO | ||
| ReturnNode() { this.asExpr() = any(ReturnExpr r).getValue() } |
There was a problem hiding this comment.
Adding a TODO for now
|
|
||
| private newtype TParameterPosition = | ||
| TReceiverParameter() or | ||
| TPositionalParameter(int n) { n = [0 .. 20] } or |
There was a problem hiding this comment.
Deliberately not implementing the accurate charpred yet. It will inevitably have to reference MaD models as possibly tuple arity and will result in time wasted on debugging if not updated at the right point in time.
Some typos and exclude constructor patterns from call graph stats Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
hvitved
left a comment
There was a problem hiding this comment.
Looks great 💪 Minor comments only.
| or | ||
| result = this.asPositional().toString() | ||
| or | ||
| result = "\"" + this.asNamed() + "\"" |
There was a problem hiding this comment.
To avoid a potentially confusing name clash with receiver. But come to think of it, suffixing with a colon would be more aligned with MaD so I'll switch to that.
| /** Gets the `CallExpr` wrapped by this dataflow call, if any. */ | ||
| CallExpr asExplicitCall() { this = TExplicitCall(result) } | ||
|
|
||
| /** Gets a string representation of this call. */ |
| predicate isBindingSite() { this instanceof NameBinding } | ||
| } | ||
|
|
||
| /** Gets implicitly-declared variable through which the given callable refers to its receiver. */ |
|
Did you run DCA? |
|
Latest DCA run should still be accurate but I'll run kick off another one. |


Enables flow through calls, using a basic call graph derived from static name resolution.
Most of the work is wiring up argument/parameter positions and post-update nodes correctly. The actual call graph is fairly trivial so far.
The PR also performs a few drive-by fixes:
p: Intinto one with an external name and a patternp p: Int. This mirrors how JS desugars short-hand properties{ p }into{ p: p }. In my experience with JS, that desugaring has proven useful and has never caused any issues so I decided to do the same here.