mirror of
https://github.com/github/codeql.git
synced 2026-06-23 05:37:02 +02:00
Shared CFG: add defaulted getLoopElse to AstSig
Adds a new defaulted signature predicates to the shared CFG library: - getLoopElse: `else` block of a loop statement, if any (used by Python's `while-else` / `for-else` constructs). The predicate defaults to `none()`, so behaviour is unchanged for any language that doesn't override it (verified by re-running java/ql/test/library-tests/controlflow/). The Make0 succession rules are extended: - WhileStmt/ForeachStmt: route the loop-exit edge through the else block before reaching the after-position. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -224,6 +224,13 @@ signature module AstSig<LocationSig Location> {
|
||||
*/
|
||||
default AstNode getTryElse(TryStmt try) { none() }
|
||||
|
||||
/**
|
||||
* Gets the `else` block of loop statement `loop`, if any.
|
||||
*
|
||||
* Only some languages (e.g. Python) support `for-else` constructs.
|
||||
*/
|
||||
default AstNode getLoopElse(LoopStmt loop) { none() }
|
||||
|
||||
/** A catch clause in a try statement. */
|
||||
class CatchClause extends AstNode {
|
||||
/** Gets the variable declared by this catch clause. */
|
||||
@@ -1578,10 +1585,17 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
|
||||
n2.isBefore(loopstmt.getBody())
|
||||
or
|
||||
n1.isAfterValue(cond, any(BooleanSuccessor b | b.getValue() = while.booleanNot())) and
|
||||
n2.isAfter(loopstmt)
|
||||
(
|
||||
n2.isBefore(getLoopElse(loopstmt))
|
||||
or
|
||||
not exists(getLoopElse(loopstmt)) and n2.isAfter(loopstmt)
|
||||
)
|
||||
or
|
||||
n1.isAfter(loopstmt.getBody()) and
|
||||
n2.isAdditional(loopstmt, loopHeaderTag())
|
||||
or
|
||||
n1.isAfter(getLoopElse(loopstmt)) and
|
||||
n2.isAfter(loopstmt)
|
||||
)
|
||||
or
|
||||
exists(ForeachStmt foreachstmt |
|
||||
@@ -1590,7 +1604,11 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
|
||||
or
|
||||
n1.isAfterValue(foreachstmt.getCollection(),
|
||||
any(EmptinessSuccessor t | t.getValue() = true)) and
|
||||
n2.isAfter(foreachstmt)
|
||||
(
|
||||
n2.isBefore(getLoopElse(foreachstmt))
|
||||
or
|
||||
not exists(getLoopElse(foreachstmt)) and n2.isAfter(foreachstmt)
|
||||
)
|
||||
or
|
||||
n1.isAfterValue(foreachstmt.getCollection(),
|
||||
any(EmptinessSuccessor t | t.getValue() = false)) and
|
||||
@@ -1603,7 +1621,11 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
|
||||
n2.isAdditional(foreachstmt, loopHeaderTag())
|
||||
or
|
||||
n1.isAdditional(foreachstmt, loopHeaderTag()) and
|
||||
n2.isAfter(foreachstmt)
|
||||
(
|
||||
n2.isBefore(getLoopElse(foreachstmt))
|
||||
or
|
||||
not exists(getLoopElse(foreachstmt)) and n2.isAfter(foreachstmt)
|
||||
)
|
||||
or
|
||||
n1.isAdditional(foreachstmt, loopHeaderTag()) and
|
||||
n2.isBefore(foreachstmt.getVariable())
|
||||
|
||||
Reference in New Issue
Block a user