Python: introduce TExpr union via newtype-branch alias

Mirror the TStmt refactor for the Expr hierarchy: rename the TExpr
newtype branch to TPyExpr and add

  private class TExpr = TPyExpr or TBoolExprPair;

This lets the public Expr class use TExpr directly:

  class Expr extends AstNodeImpl, TExpr { ... }

instead of

  class Expr extends AstNodeImpl {
    Expr() { this instanceof TExpr or this instanceof TBoolExprPair }
    ...
  }

No behaviour change: all 24 NewCfg evaluation-order tests pass; all
11 shared-CFG consistency queries report 0 violations on CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Copilot
2026-05-07 19:33:33 +00:00
parent b682877968
commit 7fefacd56f

View File

@@ -19,7 +19,7 @@ private import codeql.util.Void
module Ast implements AstSig<Py::Location> {
private newtype TAstNode =
TPyStmt(Py::Stmt s) or
TExpr(Py::Expr e) { not e instanceof Py::BoolExpr } or
TPyExpr(Py::Expr e) { not e instanceof Py::BoolExpr } or
TScope(Py::Scope sc) or
TPattern(Py::Pattern p) or
/**
@@ -53,6 +53,14 @@ module Ast implements AstSig<Py::Location> {
*/
private class TStmt = TPyStmt or TBlockStmt;
/**
* The union of `TPyExpr` (wrapping non-boolean `Py::Expr`) and
* `TBoolExprPair` (synthetic operand pairs of `and`/`or` expressions).
* Both represent the kinds of node that can appear in an `Expr`
* position in the CFG.
*/
private class TExpr = TPyExpr or TBoolExprPair;
/**
* An AST node visible to the shared CFG.
*
@@ -82,7 +90,7 @@ module Ast implements AstSig<Py::Location> {
* representation.
*/
Py::Expr asExpr() {
this = TExpr(result)
this = TPyExpr(result)
or
this = TBoolExprPair(result, 0)
}
@@ -159,10 +167,8 @@ module Ast implements AstSig<Py::Location> {
}
/** An expression. */
class Expr extends AstNodeImpl {
Expr() { this instanceof TExpr or this instanceof TBoolExprPair }
// For `TExpr` instances, delegate to the wrapped Python expression.
class Expr extends AstNodeImpl, TExpr {
// For `TPyExpr` instances, delegate to the wrapped Python expression.
// `BinaryExpr` (the only `TBoolExprPair` subclass) provides its own overrides.
override string toString() { result = this.asExpr().toString() }