mirror of
https://github.com/github/codeql.git
synced 2026-05-14 19:29:28 +02:00
Python: compact-renumber FunctionExpr/Lambda defaults
`Args.getDefault(int)` and `Args.getKwDefault(int)` are indexed by argument position (with gaps for args without defaults), not by default position. The CFG `getChild` predicate for FunctionDefExpr and LambdaExpr therefore had gaps at low indices and collisions where defaults and kwdefaults overlapped, producing parallel edges before the FunctionExpr. Use `rank` to compact-renumber `getDefault(n)` and `getKwDefault(n)` in source order. Verified on a CPython database: removes ~536 `multipleSuccessors` consistency results (1340 -> 804); the rest are `for/else` and `while/else`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -835,9 +835,22 @@ module Ast implements AstSig<Py::Location> {
|
||||
|
||||
FunctionDefExpr() { funcExpr = this.asExpr() }
|
||||
|
||||
Expr getDefault(int n) { result = TExpr(funcExpr.getArgs().getDefault(n)) }
|
||||
/**
|
||||
* Gets the `n`th default for a positional argument, in evaluation
|
||||
* order. Note that `Args.getDefault(int)` is indexed by argument
|
||||
* position (with gaps for arguments without defaults), so we must
|
||||
* renumber here to obtain contiguous indices.
|
||||
*/
|
||||
Expr getDefault(int n) {
|
||||
result =
|
||||
TExpr(rank[n + 1](Py::Expr d, int i | d = funcExpr.getArgs().getDefault(i) | d order by i))
|
||||
}
|
||||
|
||||
Expr getKwDefault(int n) { result = TExpr(funcExpr.getArgs().getKwDefault(n)) }
|
||||
/** Gets the `n`th default for a keyword-only argument, in evaluation order. */
|
||||
Expr getKwDefault(int n) {
|
||||
result =
|
||||
TExpr(rank[n + 1](Py::Expr d, int i | d = funcExpr.getArgs().getKwDefault(i) | d order by i))
|
||||
}
|
||||
|
||||
int getNumberOfDefaults() { result = count(funcExpr.getArgs().getADefault()) }
|
||||
}
|
||||
@@ -848,9 +861,17 @@ module Ast implements AstSig<Py::Location> {
|
||||
|
||||
LambdaExpr() { lambda = this.asExpr() }
|
||||
|
||||
Expr getDefault(int n) { result = TExpr(lambda.getArgs().getDefault(n)) }
|
||||
/** Gets the `n`th default for a positional argument, in evaluation order. */
|
||||
Expr getDefault(int n) {
|
||||
result =
|
||||
TExpr(rank[n + 1](Py::Expr d, int i | d = lambda.getArgs().getDefault(i) | d order by i))
|
||||
}
|
||||
|
||||
Expr getKwDefault(int n) { result = TExpr(lambda.getArgs().getKwDefault(n)) }
|
||||
/** Gets the `n`th default for a keyword-only argument, in evaluation order. */
|
||||
Expr getKwDefault(int n) {
|
||||
result =
|
||||
TExpr(rank[n + 1](Py::Expr d, int i | d = lambda.getArgs().getKwDefault(i) | d order by i))
|
||||
}
|
||||
|
||||
int getNumberOfDefaults() { result = count(lambda.getArgs().getADefault()) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user