mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
Merge pull request #15219 from rdmarsh2/rdmarsh2/swift/parameterized-cfg-library
Swift: switch to shared, parameterized CFG library
This commit is contained in:
@@ -1 +1 @@
|
||||
import codeql.swift.controlflow.internal.ControlFlowGraphImplShared::Consistency
|
||||
import codeql.swift.controlflow.internal.ControlFlowGraphImplSpecific::CfgImpl::Consistency
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The control flow graph library (`codeql.swift.controlflow`) has been transitioned to use the shared implementation from the `codeql/controlflow` qlpack. No result changes are expected due to this change.
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
private import swift
|
||||
private import ControlFlowGraph
|
||||
private import internal.ControlFlowGraphImpl
|
||||
private import internal.ControlFlowGraphImpl as Impl
|
||||
private import internal.ControlFlowElements
|
||||
private import CfgNodes
|
||||
private import SuccessorTypes
|
||||
@@ -133,7 +133,9 @@ private module Cached {
|
||||
private predicate predBB(BasicBlock succ, BasicBlock pred) { succBB(pred, succ) }
|
||||
|
||||
/** Holds if `bb` is an exit basic block that represents normal exit. */
|
||||
private predicate normalExitBB(BasicBlock bb) { bb.getANode().(AnnotatedExitNode).isNormal() }
|
||||
private predicate normalExitBB(BasicBlock bb) {
|
||||
bb.getANode().(Impl::AnnotatedExitNode).isNormal()
|
||||
}
|
||||
|
||||
/** Holds if `dom` is an immediate post-dominator of `bb`. */
|
||||
cached
|
||||
@@ -167,7 +169,9 @@ private predicate entryBB(BasicBlock bb) { bb.getFirstNode() instanceof EntryNod
|
||||
class EntryBasicBlock extends BasicBlock {
|
||||
EntryBasicBlock() { entryBB(this) }
|
||||
|
||||
override CfgScope getScope() { this.getFirstNode() = TEntryNode(result) }
|
||||
override CfgScope getScope() {
|
||||
this.getFirstNode() = any(EntryNode node | node.getScope() = result)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,7 +182,7 @@ class AnnotatedExitBasicBlock extends BasicBlock {
|
||||
private boolean normal;
|
||||
|
||||
AnnotatedExitBasicBlock() {
|
||||
exists(AnnotatedExitNode n |
|
||||
exists(Impl::AnnotatedExitNode n |
|
||||
n = this.getANode() and
|
||||
if n.isNormal() then normal = true else normal = false
|
||||
)
|
||||
|
||||
@@ -3,61 +3,10 @@
|
||||
private import swift
|
||||
private import BasicBlocks
|
||||
private import ControlFlowGraph
|
||||
private import internal.ControlFlowGraphImpl
|
||||
private import internal.ControlFlowGraphImpl as Impl
|
||||
private import internal.ControlFlowElements
|
||||
private import internal.Splitting
|
||||
|
||||
/** An entry node for a given scope. */
|
||||
class EntryNode extends ControlFlowNode, TEntryNode {
|
||||
private CfgScope scope;
|
||||
|
||||
EntryNode() { this = TEntryNode(scope) }
|
||||
|
||||
final override EntryBasicBlock getBasicBlock() { result = ControlFlowNode.super.getBasicBlock() }
|
||||
|
||||
final override Location getLocation() { result = scope.getLocation() }
|
||||
|
||||
final override string toString() { result = "enter " + scope }
|
||||
}
|
||||
|
||||
/** An exit node for a given scope, annotated with the type of exit. */
|
||||
class AnnotatedExitNode extends ControlFlowNode, TAnnotatedExitNode {
|
||||
private CfgScope scope;
|
||||
private boolean normal;
|
||||
|
||||
AnnotatedExitNode() { this = TAnnotatedExitNode(scope, normal) }
|
||||
|
||||
/** Holds if this node represent a normal exit. */
|
||||
final predicate isNormal() { normal = true }
|
||||
|
||||
final override AnnotatedExitBasicBlock getBasicBlock() {
|
||||
result = ControlFlowNode.super.getBasicBlock()
|
||||
}
|
||||
|
||||
final override Location getLocation() { result = scope.getLocation() }
|
||||
|
||||
final override string toString() {
|
||||
exists(string s |
|
||||
normal = true and s = "normal"
|
||||
or
|
||||
normal = false and s = "abnormal"
|
||||
|
|
||||
result = "exit " + scope + " (" + s + ")"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** An exit node for a given scope. */
|
||||
class ExitNode extends ControlFlowNode, TExitNode {
|
||||
private CfgScope scope;
|
||||
|
||||
ExitNode() { this = TExitNode(scope) }
|
||||
|
||||
final override Location getLocation() { result = scope.getLocation() }
|
||||
|
||||
final override string toString() { result = "exit " + scope }
|
||||
}
|
||||
|
||||
/**
|
||||
* A node for an AST node.
|
||||
*
|
||||
@@ -65,46 +14,28 @@ class ExitNode extends ControlFlowNode, TExitNode {
|
||||
* (dead) code or not important for control flow, and multiple when there are different
|
||||
* splits for the AST node.
|
||||
*/
|
||||
class CfgNode extends ControlFlowNode, TElementNode {
|
||||
private Splits splits;
|
||||
ControlFlowElement n;
|
||||
|
||||
CfgNode() { this = TElementNode(_, n, splits) }
|
||||
|
||||
final override ControlFlowElement getNode() { result = n }
|
||||
|
||||
override Location getLocation() { result = n.getLocation() }
|
||||
|
||||
final override string toString() {
|
||||
exists(string s | s = n.toString() |
|
||||
result = "[" + this.getSplitsString() + "] " + s
|
||||
or
|
||||
not exists(this.getSplitsString()) and result = s
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a comma-separated list of strings for each split in this node, if any. */
|
||||
final string getSplitsString() {
|
||||
result = splits.toString() and
|
||||
result != ""
|
||||
}
|
||||
class CfgNode extends ControlFlowNode instanceof Impl::AstCfgNode {
|
||||
final override ControlFlowElement getNode() { result = this.getAstNode() }
|
||||
|
||||
/** Gets a split for this control flow node, if any. */
|
||||
final Split getASplit() { result = splits.getASplit() }
|
||||
final Split getASplit() { result = super.getASplit() }
|
||||
|
||||
/** Gets a comma-separated list of strings for each split in this node, if any. */
|
||||
final string getSplitsString() { result = super.getSplitsString() }
|
||||
|
||||
/** Gets the AST representation of this control flow node, if any. */
|
||||
Expr getAst() {
|
||||
result = n.asAstNode()
|
||||
result = this.getNode().asAstNode()
|
||||
or
|
||||
result = n.(PropertyGetterElement).getRef()
|
||||
result = this.getNode().(PropertyGetterElement).getRef()
|
||||
or
|
||||
result = n.(PropertySetterElement).getAssignExpr()
|
||||
result = this.getNode().(PropertySetterElement).getAssignExpr()
|
||||
or
|
||||
result = n.(PropertyObserverElement).getAssignExpr()
|
||||
result = this.getNode().(PropertyObserverElement).getAssignExpr()
|
||||
or
|
||||
result = n.(ClosureElement).getAst()
|
||||
result = this.getNode().(ClosureElement).getAst()
|
||||
or
|
||||
result = n.(KeyPathElement).getAst()
|
||||
result = this.getNode().(KeyPathElement).getAst()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +61,9 @@ class PatternCfgNode extends CfgNode {
|
||||
|
||||
/** A control-flow node that wraps a property getter. */
|
||||
class PropertyGetterCfgNode extends CfgNode {
|
||||
override PropertyGetterElement n;
|
||||
PropertyGetterElement n;
|
||||
|
||||
PropertyGetterCfgNode() { n = this.getAstNode() }
|
||||
|
||||
Expr getRef() { result = n.getRef() }
|
||||
|
||||
@@ -141,7 +74,9 @@ class PropertyGetterCfgNode extends CfgNode {
|
||||
|
||||
/** A control-flow node that wraps a property setter. */
|
||||
class PropertySetterCfgNode extends CfgNode {
|
||||
override PropertySetterElement n;
|
||||
PropertySetterElement n;
|
||||
|
||||
PropertySetterCfgNode() { n = this.getAstNode() }
|
||||
|
||||
AssignExpr getAssignExpr() { result = n.getAssignExpr() }
|
||||
|
||||
@@ -153,7 +88,9 @@ class PropertySetterCfgNode extends CfgNode {
|
||||
}
|
||||
|
||||
class PropertyObserverCfgNode extends CfgNode {
|
||||
override PropertyObserverElement n;
|
||||
PropertyObserverElement n;
|
||||
|
||||
PropertyObserverCfgNode() { n = this.getAstNode() }
|
||||
|
||||
AssignExpr getAssignExpr() { result = n.getAssignExpr() }
|
||||
|
||||
@@ -201,3 +138,9 @@ class KeyPathApplicationExprCfgNode extends ExprCfgNode {
|
||||
class KeyPathExprCfgNode extends ExprCfgNode {
|
||||
override KeyPathExpr e;
|
||||
}
|
||||
|
||||
class EntryNode = Impl::EntryNode;
|
||||
|
||||
class ExitNode = Impl::ExitNode;
|
||||
|
||||
class AnnotatedExitNode = Impl::AnnotatedExitNode;
|
||||
|
||||
@@ -27,16 +27,10 @@ class CfgScope extends Scope instanceof CfgScope::Range_ {
|
||||
*
|
||||
* Only nodes that can be reached from an entry point are included in the CFG.
|
||||
*/
|
||||
class ControlFlowNode extends TCfgNode {
|
||||
/** Gets a textual representation of this control flow node. */
|
||||
string toString() { none() }
|
||||
|
||||
class ControlFlowNode extends Node {
|
||||
/** Gets the AST node that this node corresponds to, if any. */
|
||||
ControlFlowElement getNode() { none() }
|
||||
|
||||
/** Gets the location of this control flow node. */
|
||||
Location getLocation() { none() }
|
||||
|
||||
/** Gets the file of this control flow node. */
|
||||
final File getFile() { result = this.getLocation().getFile() }
|
||||
|
||||
@@ -50,7 +44,7 @@ class ControlFlowNode extends TCfgNode {
|
||||
BasicBlock getBasicBlock() { result.getANode() = this }
|
||||
|
||||
/** Gets a successor node of a given type, if any. */
|
||||
final ControlFlowNode getASuccessor(SuccessorType t) { result = getASuccessor(this, t) }
|
||||
final ControlFlowNode getASuccessor(SuccessorType t) { result = super.getASuccessor(t) }
|
||||
|
||||
/** Gets an immediate successor, if any. */
|
||||
final ControlFlowNode getASuccessor() { result = this.getASuccessor(_) }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
private import swift
|
||||
private import Completion
|
||||
private import ControlFlowGraphImplShared
|
||||
private import ControlFlowGraphImplSpecific::CfgImpl
|
||||
private import ControlFlowElements
|
||||
|
||||
abstract class AstControlFlowTree extends ControlFlowTree {
|
||||
|
||||
@@ -36,7 +36,7 @@ private import codeql.swift.controlflow.ControlFlowGraph
|
||||
private import codeql.swift.generated.Synth
|
||||
private import Completion
|
||||
private import Scope
|
||||
import ControlFlowGraphImplShared
|
||||
import ControlFlowGraphImplSpecific::CfgImpl
|
||||
private import ControlFlowElements
|
||||
private import AstControlFlowTrees
|
||||
|
||||
@@ -80,10 +80,12 @@ module CfgScope {
|
||||
final override predicate exit(ControlFlowElement last, Completion c) { last(tree, last, c) }
|
||||
}
|
||||
|
||||
private class KeyPathControlFlowTree extends StandardPostOrderTree, KeyPathElement {
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
result.asAstNode() = expr.getComponent(i)
|
||||
private class KeyPathControlFlowTree extends StandardPostOrderTree instanceof KeyPathElement {
|
||||
override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = super.getAst().getComponent(i)
|
||||
}
|
||||
|
||||
KeyPathExpr getAst() { result = super.getAst() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +102,7 @@ predicate succExit(CfgScope::Range_ scope, ControlFlowElement last, Completion c
|
||||
private class KeyPathComponentTree extends AstStandardPostOrderTree {
|
||||
override KeyPathComponent ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getSubscriptArgument(i).getExpr().getFullyConverted()
|
||||
}
|
||||
}
|
||||
@@ -232,7 +234,7 @@ module Stmts {
|
||||
private class ReturnStmtTree extends AstStandardPostOrderTree {
|
||||
override ReturnStmt ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getResult().getFullyConverted() and i = 0
|
||||
}
|
||||
}
|
||||
@@ -240,7 +242,7 @@ module Stmts {
|
||||
private class DiscardStmtTree extends AstStandardPostOrderTree {
|
||||
override DiscardStmt ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and result.asAstNode() = ast.getSubExpr().getFullyUnresolved()
|
||||
}
|
||||
}
|
||||
@@ -248,7 +250,7 @@ module Stmts {
|
||||
private class YieldStmtTree extends AstStandardPostOrderTree {
|
||||
override YieldStmt ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getResult(i).getFullyConverted()
|
||||
}
|
||||
}
|
||||
@@ -822,7 +824,7 @@ module Patterns {
|
||||
private class TypedTree extends AstStandardPostOrderTree {
|
||||
override TypedPattern ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and
|
||||
result.asAstNode() = ast.getSubPattern().getFullyUnresolved()
|
||||
}
|
||||
@@ -863,7 +865,7 @@ module Patterns {
|
||||
private class ParenTree extends AstStandardPreOrderTree {
|
||||
override ParenPattern ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and
|
||||
result.asAstNode() = ast.getResolveStep()
|
||||
}
|
||||
@@ -884,7 +886,7 @@ module Patterns {
|
||||
private class IsTree extends AstStandardPostOrderTree {
|
||||
override IsPattern ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
// Note: `getSubPattern` only has a result if the `is` pattern is of the form `pattern as type`.
|
||||
i = 0 and
|
||||
result.asAstNode() = ast.getSubPattern().getFullyUnresolved()
|
||||
@@ -924,7 +926,7 @@ module Patterns {
|
||||
private class BindingTree extends AstStandardPostOrderTree {
|
||||
override BindingPattern ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and
|
||||
result.asAstNode() = ast.getResolveStep()
|
||||
}
|
||||
@@ -933,7 +935,7 @@ module Patterns {
|
||||
private class ExprTree extends AstStandardPostOrderTree {
|
||||
override ExprPattern ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted()
|
||||
}
|
||||
@@ -973,7 +975,7 @@ module Decls {
|
||||
private class PatternBindingDeclTree extends AstStandardPostOrderTree {
|
||||
override PatternBindingDecl ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
exists(int j |
|
||||
i = 2 * j and
|
||||
result.asAstNode() = ast.getPattern(j).getFullyUnresolved()
|
||||
@@ -1033,7 +1035,7 @@ module Decls {
|
||||
|
||||
Function getAst() { result = ast }
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = -1 and
|
||||
result.asAstNode() = ast.getSelfParam()
|
||||
or
|
||||
@@ -1167,7 +1169,7 @@ module Exprs {
|
||||
|
||||
ClosureExpr getAst() { result = expr }
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = expr.getParam(i)
|
||||
or
|
||||
result.asAstNode() = expr.getBody() and
|
||||
@@ -1178,7 +1180,7 @@ module Exprs {
|
||||
private class BindOptionalTree extends AstStandardPostOrderTree {
|
||||
override BindOptionalExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0
|
||||
}
|
||||
}
|
||||
@@ -1186,7 +1188,7 @@ module Exprs {
|
||||
private class CaptureListTree extends AstStandardPostOrderTree {
|
||||
override CaptureListExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getBindingDecl(i).getFullyUnresolved()
|
||||
or
|
||||
i = ast.getNumberOfBindingDecls() and
|
||||
@@ -1255,7 +1257,7 @@ module Exprs {
|
||||
class KeyPathApplicationTree extends AstStandardPostOrderTree {
|
||||
override KeyPathApplicationExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and result.asAstNode() = ast.getBase().getFullyConverted()
|
||||
or
|
||||
i = 1 and result.asAstNode() = ast.getKeyPath().getFullyConverted()
|
||||
@@ -1313,7 +1315,7 @@ module Exprs {
|
||||
private class TupleTree extends AstStandardPostOrderTree {
|
||||
override TupleExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getElement(i).getFullyConverted()
|
||||
}
|
||||
}
|
||||
@@ -1321,7 +1323,7 @@ module Exprs {
|
||||
private class TupleElementTree extends AstStandardPostOrderTree {
|
||||
override TupleElementExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0
|
||||
}
|
||||
}
|
||||
@@ -1329,7 +1331,7 @@ module Exprs {
|
||||
private class RebindSelfInInitializerTree extends AstStandardPostOrderTree {
|
||||
override RebindSelfInInitializerExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0
|
||||
}
|
||||
}
|
||||
@@ -1341,7 +1343,7 @@ module Exprs {
|
||||
private class DotSyntaxBaseIgnoredTree extends AstStandardPostOrderTree {
|
||||
override DotSyntaxBaseIgnoredExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getQualifier().getFullyConverted() and i = 0
|
||||
or
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 1
|
||||
@@ -1355,7 +1357,7 @@ module Exprs {
|
||||
private class DynamicTypeTree extends AstStandardPostOrderTree {
|
||||
override DynamicTypeExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getBase().getFullyConverted() and i = 0
|
||||
}
|
||||
}
|
||||
@@ -1363,7 +1365,7 @@ module Exprs {
|
||||
private class LazyInitializationTree extends AstStandardPostOrderTree {
|
||||
override LazyInitializationExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0
|
||||
}
|
||||
}
|
||||
@@ -1371,7 +1373,7 @@ module Exprs {
|
||||
private class ObjCSelectorTree extends AstStandardPostOrderTree {
|
||||
override ObjCSelectorExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0
|
||||
}
|
||||
}
|
||||
@@ -1379,7 +1381,7 @@ module Exprs {
|
||||
private class OneWayTree extends AstStandardPostOrderTree {
|
||||
override OneWayExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0
|
||||
}
|
||||
}
|
||||
@@ -1387,7 +1389,7 @@ module Exprs {
|
||||
private class OptionalEvaluationTree extends AstStandardPostOrderTree {
|
||||
override OptionalEvaluationExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0
|
||||
}
|
||||
}
|
||||
@@ -1404,7 +1406,7 @@ module Exprs {
|
||||
private class InterpolatedStringLiteralExprTree extends AstStandardPostOrderTree {
|
||||
override InterpolatedStringLiteralExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and
|
||||
result.asAstNode() = ast.getAppendingExpr().getFullyConverted()
|
||||
}
|
||||
@@ -1414,7 +1416,7 @@ module Exprs {
|
||||
private class TapExprTree extends AstStandardPostOrderTree {
|
||||
override TapExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
// We first visit the expression that gives the local variable its initial value.
|
||||
i = 0 and
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted()
|
||||
@@ -1429,7 +1431,7 @@ module Exprs {
|
||||
private class SingleValueStmtExprTree extends AstStandardPostOrderTree {
|
||||
override SingleValueStmtExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and result.asAstNode() = ast.getStmt()
|
||||
}
|
||||
}
|
||||
@@ -1438,7 +1440,7 @@ module Exprs {
|
||||
private class PackExpansionExprTree extends AstStandardPostOrderTree {
|
||||
override PackExpansionExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and result.asAstNode() = ast.getPatternExpr().getFullyConverted()
|
||||
}
|
||||
}
|
||||
@@ -1447,7 +1449,7 @@ module Exprs {
|
||||
private class PackElementExprTree extends AstStandardPostOrderTree {
|
||||
override PackElementExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and result.asAstNode() = ast.getSubExpr().getFullyUnresolved()
|
||||
}
|
||||
}
|
||||
@@ -1455,7 +1457,7 @@ module Exprs {
|
||||
private class MaterializePackExprTree extends AstStandardPostOrderTree {
|
||||
override MaterializePackExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and result.asAstNode() = ast.getSubExpr().getFullyUnresolved()
|
||||
}
|
||||
}
|
||||
@@ -1464,7 +1466,7 @@ module Exprs {
|
||||
private class CopyExprTree extends AstStandardPostOrderTree {
|
||||
override CopyExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and result.asAstNode() = ast.getSubExpr().getFullyUnresolved()
|
||||
}
|
||||
}
|
||||
@@ -1473,7 +1475,7 @@ module Exprs {
|
||||
private class ConsumeExprTree extends AstStandardPostOrderTree {
|
||||
override ConsumeExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and result.asAstNode() = ast.getSubExpr().getFullyUnresolved()
|
||||
}
|
||||
}
|
||||
@@ -1535,7 +1537,7 @@ module Exprs {
|
||||
class MethodLookupExprTree extends AstStandardPreOrderTree {
|
||||
override MethodLookupExpr ast;
|
||||
|
||||
override ControlFlowElement getChildElement(int i) {
|
||||
override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and result.asAstNode() = ast.getBase().getFullyConverted()
|
||||
}
|
||||
}
|
||||
@@ -1642,7 +1644,7 @@ module Exprs {
|
||||
not ast instanceof NilCoalescingExpr
|
||||
}
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = -1 and
|
||||
result.asAstNode() = ast.getFunction().getFullyConverted()
|
||||
or
|
||||
@@ -1657,13 +1659,15 @@ module Exprs {
|
||||
private class ForceValueTree extends AstStandardPostOrderTree {
|
||||
override ForceValueExpr ast;
|
||||
|
||||
override ControlFlowElement getChildElement(int i) {
|
||||
override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted()
|
||||
}
|
||||
}
|
||||
|
||||
private class NilCoalescingTestTree extends LeafTree, NilCoalescingElement { }
|
||||
private class NilCoalescingTestTree extends LeafTree instanceof NilCoalescingElement {
|
||||
NilCoalescingExpr getAst() { result = super.getAst() }
|
||||
}
|
||||
|
||||
private class NilCoalescingTree extends AstPostOrderTree {
|
||||
override NilCoalescingExpr ast;
|
||||
@@ -1768,7 +1772,7 @@ module Exprs {
|
||||
private class VarargExpansionTree extends AstStandardPostOrderTree {
|
||||
override VarargExpansionExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted()
|
||||
}
|
||||
@@ -1777,7 +1781,7 @@ module Exprs {
|
||||
private class ArrayTree extends AstStandardPostOrderTree {
|
||||
override ArrayExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getElement(i).getFullyConverted()
|
||||
}
|
||||
}
|
||||
@@ -1785,7 +1789,7 @@ module Exprs {
|
||||
private class EnumIsCaseTree extends AstStandardPostOrderTree {
|
||||
override EnumIsCaseExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0
|
||||
}
|
||||
}
|
||||
@@ -1793,7 +1797,7 @@ module Exprs {
|
||||
private class IsTree extends AstStandardPostOrderTree {
|
||||
override IsExpr ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0
|
||||
}
|
||||
}
|
||||
@@ -1827,7 +1831,7 @@ module Exprs {
|
||||
private class AnyTryTree extends AstStandardPostOrderTree {
|
||||
override AnyTryExpr ast;
|
||||
|
||||
override ControlFlowElement getChildElement(int i) {
|
||||
override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and
|
||||
result.asAstNode() = ast.getSubExpr().getFullyConverted()
|
||||
}
|
||||
@@ -1836,7 +1840,7 @@ module Exprs {
|
||||
private class DictionaryLiteralTree extends AstStandardPostOrderTree {
|
||||
override DictionaryExpr ast;
|
||||
|
||||
override ControlFlowElement getChildElement(int i) {
|
||||
override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getElement(i).getFullyConverted()
|
||||
}
|
||||
}
|
||||
@@ -1844,7 +1848,7 @@ module Exprs {
|
||||
private class OpenExistentialTree extends AstStandardPostOrderTree {
|
||||
override OpenExistentialExpr ast;
|
||||
|
||||
override ControlFlowElement getChildElement(int i) {
|
||||
override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and
|
||||
result.asAstNode() = ast.getExistential().getFullyConverted()
|
||||
or
|
||||
@@ -1863,7 +1867,7 @@ module Exprs {
|
||||
|
||||
abstract predicate convertsFrom(Expr e);
|
||||
|
||||
override ControlFlowElement getChildElement(int i) {
|
||||
override ControlFlowElement getChildNode(int i) {
|
||||
i = 0 and
|
||||
this.convertsFrom(result.asAstNode())
|
||||
}
|
||||
@@ -1900,7 +1904,7 @@ module AvailabilityInfo {
|
||||
private class AvailabilityInfoTree extends AstStandardPostOrderTree {
|
||||
override AvailabilityInfo ast;
|
||||
|
||||
final override ControlFlowElement getChildElement(int i) {
|
||||
final override ControlFlowElement getChildNode(int i) {
|
||||
result.asAstNode() = ast.getSpec(i).getFullyUnresolved()
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,18 @@
|
||||
/**
|
||||
* Provides the `CfgImpl` module that is used to construct the basic successor relation on control
|
||||
* flow elements, and the `CfgInput` module that is used to construct `CgfImpl`.
|
||||
*
|
||||
* See `ControlFlowGraphImpl.qll` for the auxiliary classes and predicates that map AST elements to
|
||||
* control flow elements and sequence their children.
|
||||
*/
|
||||
|
||||
private import swift as S
|
||||
import codeql.controlflow.Cfg
|
||||
import codeql.util.Unit
|
||||
private import Completion as C
|
||||
private import ControlFlowGraphImpl as Impl
|
||||
import Completion
|
||||
private import codeql.swift.controlflow.ControlFlowGraph as CFG
|
||||
private import codeql.swift.controlflow.ControlFlowGraph as Cfg
|
||||
private import Splitting as Splitting
|
||||
private import Scope
|
||||
import ControlFlowElements
|
||||
@@ -10,45 +21,71 @@ import AstControlFlowTrees
|
||||
/** The base class for `ControlFlowTree`. */
|
||||
class ControlFlowTreeBase = ControlFlowElement;
|
||||
|
||||
class CfgScope = CFG::CfgScope;
|
||||
class CfgScope = Cfg::CfgScope;
|
||||
|
||||
predicate getCfgScope = Impl::getCfgScope/1;
|
||||
|
||||
/** Holds if `first` is first executed when entering `scope`. */
|
||||
predicate scopeFirst(CfgScope scope, ControlFlowElement first) {
|
||||
scope.(Impl::CfgScope::Range_).entry(first)
|
||||
}
|
||||
|
||||
/** Holds if `scope` is exited when `last` finishes with completion `c`. */
|
||||
predicate scopeLast(CfgScope scope, ControlFlowElement last, Completion c) {
|
||||
scope.(Impl::CfgScope::Range_).exit(last, c)
|
||||
}
|
||||
|
||||
/** Gets the maximum number of splits allowed for a given node. */
|
||||
int maxSplits() { result = 5 }
|
||||
|
||||
class SplitKindBase = Splitting::TSplitKind;
|
||||
|
||||
class Split = Splitting::Split;
|
||||
|
||||
class SuccessorType = CFG::SuccessorType;
|
||||
|
||||
/** Gets a successor type that matches completion `c`. */
|
||||
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
|
||||
|
||||
/**
|
||||
* Hold if `c` represents simple (normal) evaluation of a statement or an
|
||||
* expression.
|
||||
*/
|
||||
predicate successorTypeIsSimple(SuccessorType t) {
|
||||
t instanceof CFG::SuccessorTypes::NormalSuccessor
|
||||
}
|
||||
|
||||
/** Holds if `t` is an abnormal exit type out of a CFG scope. */
|
||||
predicate isAbnormalExitType(SuccessorType t) {
|
||||
t instanceof CFG::SuccessorTypes::ExceptionSuccessor
|
||||
}
|
||||
|
||||
class Location = S::Location;
|
||||
|
||||
class Node = CFG::ControlFlowNode;
|
||||
class Node = Cfg::ControlFlowNode;
|
||||
|
||||
module CfgInput implements InputSig<Location> {
|
||||
class AstNode = ControlFlowElement;
|
||||
|
||||
class Completion = C::Completion;
|
||||
|
||||
predicate completionIsNormal = C::completionIsNormal/1;
|
||||
|
||||
predicate completionIsSimple = C::completionIsSimple/1;
|
||||
|
||||
predicate completionIsValidFor = C::completionIsValidFor/2;
|
||||
|
||||
/** An AST node with an associated control-flow graph. */
|
||||
class CfgScope extends S::Locatable instanceof Impl::CfgScope::Range_ { }
|
||||
|
||||
CfgScope getCfgScope(AstNode n) { result = scopeOfAst(n.asAstNode()) }
|
||||
|
||||
class SplitKindBase = Splitting::TSplitKind;
|
||||
|
||||
class Split = Splitting::Split;
|
||||
|
||||
class SuccessorType = Cfg::SuccessorType;
|
||||
|
||||
/** Gets a successor type that matches completion `c`. */
|
||||
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
|
||||
|
||||
/**
|
||||
* Hold if `c` represents simple (normal) evaluation of a statement or an
|
||||
* expression.
|
||||
*/
|
||||
predicate successorTypeIsSimple(SuccessorType t) {
|
||||
t instanceof Cfg::SuccessorTypes::NormalSuccessor
|
||||
}
|
||||
|
||||
/** Holds if `t` is an abnormal exit type out of a CFG scope. */
|
||||
predicate isAbnormalExitType(SuccessorType t) {
|
||||
t instanceof Cfg::SuccessorTypes::ExceptionSuccessor
|
||||
}
|
||||
|
||||
/** Hold if `t` represents a conditional successor type. */
|
||||
predicate successorTypeIsCondition(SuccessorType t) {
|
||||
t instanceof Cfg::SuccessorTypes::BooleanSuccessor or
|
||||
t instanceof Cfg::SuccessorTypes::BreakSuccessor or
|
||||
t instanceof Cfg::SuccessorTypes::ContinueSuccessor or
|
||||
t instanceof Cfg::SuccessorTypes::MatchingSuccessor or
|
||||
t instanceof Cfg::SuccessorTypes::EmptinessSuccessor
|
||||
}
|
||||
|
||||
/** Holds if `first` is first executed when entering `scope`. */
|
||||
predicate scopeFirst(CfgScope scope, AstNode first) {
|
||||
scope.(Impl::CfgScope::Range_).entry(first)
|
||||
}
|
||||
|
||||
/** Holds if `scope` is exited when `last` finishes with completion `c`. */
|
||||
predicate scopeLast(CfgScope scope, AstNode last, Completion c) {
|
||||
scope.(Impl::CfgScope::Range_).exit(last, c)
|
||||
}
|
||||
}
|
||||
|
||||
module CfgImpl = Make<Location, CfgInput>;
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
private import swift
|
||||
private import Completion
|
||||
private import ControlFlowGraphImpl
|
||||
private import codeql.swift.controlflow.ControlFlowGraph
|
||||
private import AstControlFlowTrees
|
||||
private import ControlFlowElements
|
||||
private import ControlFlowGraphImplSpecific::CfgInput as CfgInput
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
@@ -33,6 +33,8 @@ private module ConditionalCompletionSplitting {
|
||||
|
||||
ConditionalCompletionSplit() { this = TConditionalCompletionSplit(completion) }
|
||||
|
||||
ConditionalCompletion getCompletion() { result = completion }
|
||||
|
||||
override string toString() { result = completion.toString() }
|
||||
}
|
||||
|
||||
@@ -44,49 +46,50 @@ private module ConditionalCompletionSplitting {
|
||||
override string toString() { result = "ConditionalCompletion" }
|
||||
}
|
||||
|
||||
private class ConditionalCompletionSplitImpl extends SplitImpl, ConditionalCompletionSplit {
|
||||
private class ConditionalCompletionSplitImpl extends SplitImpl instanceof ConditionalCompletionSplit
|
||||
{
|
||||
override ConditionalCompletionSplitKind getKind() { any() }
|
||||
|
||||
override predicate hasEntry(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
|
||||
succ(pred, succ, c) and
|
||||
last(succ, _, completion) and
|
||||
last(succ, _, super.getCompletion()) and
|
||||
(
|
||||
astLast(succ.asAstNode().(NotExpr).getOperand().getFullyConverted(), pred, c) and
|
||||
completion.(BooleanCompletion).getDual() = c
|
||||
super.getCompletion().(BooleanCompletion).getDual() = c
|
||||
or
|
||||
astLast(succ.asAstNode().(LogicalAndExpr).getAnOperand().getFullyConverted(), pred, c) and
|
||||
completion = c
|
||||
super.getCompletion() = c
|
||||
or
|
||||
astLast(succ.asAstNode().(LogicalOrExpr).getAnOperand().getFullyConverted(), pred, c) and
|
||||
completion = c
|
||||
super.getCompletion() = c
|
||||
or
|
||||
succ.asAstNode() =
|
||||
any(IfExpr ce |
|
||||
astLast(ce.getBranch(_).getFullyConverted(), pred, c) and
|
||||
completion = c
|
||||
super.getCompletion() = c
|
||||
)
|
||||
or
|
||||
exists(Expr e, Exprs::Conversions::ConversionOrIdentityTree conv |
|
||||
succ.asAstNode() = conv.getAst() and
|
||||
conv.convertsFrom(e) and
|
||||
astLast(e, pred, c) and
|
||||
completion = c
|
||||
super.getCompletion() = c
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasEntryScope(CfgScope scope, ControlFlowElement succ) { none() }
|
||||
override predicate hasEntryScope(CfgInput::CfgScope scope, ControlFlowElement succ) { none() }
|
||||
|
||||
override predicate hasExit(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
|
||||
this.appliesTo(pred) and
|
||||
succ(pred, succ, c) and
|
||||
if c instanceof ConditionalCompletion then completion = c else any()
|
||||
if c instanceof ConditionalCompletion then super.getCompletion() = c else any()
|
||||
}
|
||||
|
||||
override predicate hasExitScope(CfgScope scope, ControlFlowElement last, Completion c) {
|
||||
override predicate hasExitScope(CfgInput::CfgScope scope, ControlFlowElement last, Completion c) {
|
||||
this.appliesTo(last) and
|
||||
succExit(scope, last, c) and
|
||||
if c instanceof ConditionalCompletion then completion = c else any()
|
||||
if c instanceof ConditionalCompletion then super.getCompletion() = c else any()
|
||||
}
|
||||
|
||||
override predicate hasSuccessor(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
|
||||
|
||||
@@ -6,6 +6,7 @@ dbscheme: swift.dbscheme
|
||||
upgrades: upgrades
|
||||
library: true
|
||||
dependencies:
|
||||
codeql/controlflow: ${workspace}
|
||||
codeql/dataflow: ${workspace}
|
||||
codeql/regex: ${workspace}
|
||||
codeql/mad: ${workspace}
|
||||
|
||||
@@ -1,3 +1,252 @@
|
||||
#-----| ... = ...
|
||||
#-----| -> exit set (normal)
|
||||
|
||||
#-----| ... = ...
|
||||
#-----| -> exit set (normal)
|
||||
|
||||
#-----| ... = ...
|
||||
#-----| -> exit set (normal)
|
||||
|
||||
#-----| ... = ...
|
||||
#-----| -> exit set (normal)
|
||||
|
||||
#-----| ... = ...
|
||||
#-----| -> exit set (normal)
|
||||
|
||||
#-----| ... = ...
|
||||
#-----| -> exit set (normal)
|
||||
|
||||
#-----| ... = ...
|
||||
#-----| -> exit set (normal)
|
||||
|
||||
#-----| &...
|
||||
#-----| -> yield ...
|
||||
|
||||
#-----| &...
|
||||
#-----| -> yield ...
|
||||
|
||||
#-----| &...
|
||||
#-----| -> yield ...
|
||||
|
||||
#-----| &...
|
||||
#-----| -> yield ...
|
||||
|
||||
#-----| &...
|
||||
#-----| -> yield ...
|
||||
|
||||
#-----| &...
|
||||
#-----| -> yield ...
|
||||
|
||||
#-----| &...
|
||||
#-----| -> yield ...
|
||||
|
||||
#-----| .b
|
||||
#-----| -> return ...
|
||||
|
||||
#-----| .b
|
||||
#-----| -> value
|
||||
|
||||
#-----| .bs
|
||||
#-----| -> return ...
|
||||
|
||||
#-----| .bs
|
||||
#-----| -> value
|
||||
|
||||
#-----| .c
|
||||
#-----| -> return ...
|
||||
|
||||
#-----| .field
|
||||
#-----| -> return ...
|
||||
|
||||
#-----| .field
|
||||
#-----| -> value
|
||||
|
||||
#-----| .mayB
|
||||
#-----| -> return ...
|
||||
|
||||
#-----| .mayB
|
||||
#-----| -> value
|
||||
|
||||
#-----| .myInt
|
||||
#-----| -> return ...
|
||||
|
||||
#-----| .x
|
||||
#-----| -> return ...
|
||||
|
||||
#-----| .x
|
||||
#-----| -> value
|
||||
|
||||
#-----| .x
|
||||
#-----| -> return ...
|
||||
|
||||
#-----| .x
|
||||
#-----| -> value
|
||||
|
||||
#-----| .x
|
||||
#-----| -> return ...
|
||||
|
||||
#-----| .x
|
||||
#-----| -> value
|
||||
|
||||
#-----| KeyPathComponent
|
||||
#-----| -> #keyPath(...)
|
||||
|
||||
#-----| await ...
|
||||
#-----| -> for ... in ... { ... }
|
||||
|
||||
#-----| getter for .b
|
||||
#-----| -> &...
|
||||
|
||||
#-----| getter for .bs
|
||||
#-----| -> &...
|
||||
|
||||
#-----| getter for .field
|
||||
#-----| -> &...
|
||||
|
||||
#-----| getter for .mayB
|
||||
#-----| -> &...
|
||||
|
||||
#-----| getter for .x
|
||||
#-----| -> &...
|
||||
|
||||
#-----| getter for .x
|
||||
#-----| -> &...
|
||||
|
||||
#-----| getter for .x
|
||||
#-----| -> &...
|
||||
|
||||
#-----| n
|
||||
#-----| -> _unimplementedInitializer(className:initName:file:line:column:)
|
||||
|
||||
#-----| return
|
||||
#-----| return -> exit Derived.init(n:) (normal)
|
||||
|
||||
#-----| return ...
|
||||
#-----| return -> exit get (normal)
|
||||
|
||||
#-----| return ...
|
||||
#-----| return -> exit get (normal)
|
||||
|
||||
#-----| return ...
|
||||
#-----| return -> exit get (normal)
|
||||
|
||||
#-----| return ...
|
||||
#-----| return -> exit get (normal)
|
||||
|
||||
#-----| return ...
|
||||
#-----| return -> exit get (normal)
|
||||
|
||||
#-----| return ...
|
||||
#-----| return -> exit get (normal)
|
||||
|
||||
#-----| return ...
|
||||
#-----| return -> exit get (normal)
|
||||
|
||||
#-----| return ...
|
||||
#-----| return -> exit get (normal)
|
||||
|
||||
#-----| return ...
|
||||
#-----| return -> exit get (normal)
|
||||
|
||||
#-----| self
|
||||
#-----| -> .myInt
|
||||
|
||||
#-----| self
|
||||
#-----| -> .c
|
||||
|
||||
#-----| self
|
||||
#-----| -> .field
|
||||
|
||||
#-----| self
|
||||
#-----| -> .field
|
||||
|
||||
#-----| self
|
||||
#-----| -> getter for .field
|
||||
|
||||
#-----| self
|
||||
#-----| -> .x
|
||||
|
||||
#-----| self
|
||||
#-----| -> .x
|
||||
|
||||
#-----| self
|
||||
#-----| -> getter for .x
|
||||
|
||||
#-----| self
|
||||
#-----| -> .x
|
||||
|
||||
#-----| self
|
||||
#-----| -> .x
|
||||
|
||||
#-----| self
|
||||
#-----| -> getter for .x
|
||||
|
||||
#-----| self
|
||||
#-----| -> .x
|
||||
|
||||
#-----| self
|
||||
#-----| -> .x
|
||||
|
||||
#-----| self
|
||||
#-----| -> getter for .x
|
||||
|
||||
#-----| self
|
||||
#-----| -> .mayB
|
||||
|
||||
#-----| self
|
||||
#-----| -> .mayB
|
||||
|
||||
#-----| self
|
||||
#-----| -> getter for .mayB
|
||||
|
||||
#-----| self
|
||||
#-----| -> .bs
|
||||
|
||||
#-----| self
|
||||
#-----| -> .bs
|
||||
|
||||
#-----| self
|
||||
#-----| -> getter for .bs
|
||||
|
||||
#-----| self
|
||||
#-----| -> .b
|
||||
|
||||
#-----| self
|
||||
#-----| -> .b
|
||||
|
||||
#-----| self
|
||||
#-----| -> getter for .b
|
||||
|
||||
#-----| value
|
||||
#-----| -> ... = ...
|
||||
|
||||
#-----| value
|
||||
#-----| -> ... = ...
|
||||
|
||||
#-----| value
|
||||
#-----| -> ... = ...
|
||||
|
||||
#-----| value
|
||||
#-----| -> ... = ...
|
||||
|
||||
#-----| value
|
||||
#-----| -> ... = ...
|
||||
|
||||
#-----| value
|
||||
#-----| -> ... = ...
|
||||
|
||||
#-----| value
|
||||
#-----| -> ... = ...
|
||||
|
||||
#-----| var ... = ...
|
||||
#-----| -> .next()
|
||||
|
||||
#-----| var ... = ...
|
||||
#-----| -> .next()
|
||||
|
||||
#-----| var ... = ...
|
||||
#-----| -> .next()
|
||||
|
||||
cfg.swift:
|
||||
# 5| enter returnZero()
|
||||
#-----| -> returnZero()
|
||||
@@ -956,6 +1205,7 @@ cfg.swift:
|
||||
#-----| -> self
|
||||
|
||||
# 99| self
|
||||
#-----| -> self
|
||||
|
||||
# 100| self
|
||||
#-----| -> n
|
||||
@@ -1456,6 +1706,7 @@ cfg.swift:
|
||||
#-----| -> ....(_:_:)
|
||||
|
||||
# 138| call to makeIterator()
|
||||
#-----| -> var ... = ...
|
||||
|
||||
# 138| ....(_:_:)
|
||||
#-----| -> Int.Type
|
||||
@@ -4606,6 +4857,7 @@ cfg.swift:
|
||||
#-----| -> self
|
||||
|
||||
# 353| self
|
||||
#-----| -> self
|
||||
|
||||
# 354| self
|
||||
#-----| -> arg
|
||||
@@ -4875,6 +5127,7 @@ cfg.swift:
|
||||
#-----| -> cfg.Derived
|
||||
|
||||
# 377| call to _unimplementedInitializer(className:initName:file:line:column:)
|
||||
#-----| -> return
|
||||
|
||||
# 377| cfg.Derived
|
||||
#-----| -> #...
|
||||
@@ -4905,6 +5158,7 @@ cfg.swift:
|
||||
#-----| -> exit Derived.init(n:)
|
||||
|
||||
# 377| self
|
||||
#-----| -> n
|
||||
|
||||
# 378| self
|
||||
#-----| -> C.init(n:)
|
||||
@@ -5069,16 +5323,19 @@ cfg.swift:
|
||||
#-----| -> self
|
||||
|
||||
# 394| self
|
||||
#-----| -> self
|
||||
|
||||
# 394| self
|
||||
#-----| -> value
|
||||
|
||||
# 394| self
|
||||
#-----| -> self
|
||||
|
||||
# 394| set
|
||||
#-----| -> self
|
||||
|
||||
# 394| value
|
||||
#-----| -> self
|
||||
|
||||
# 394| yield ...
|
||||
#-----| -> exit _modify (normal)
|
||||
@@ -5241,16 +5498,19 @@ cfg.swift:
|
||||
#-----| -> self
|
||||
|
||||
# 410| self
|
||||
#-----| -> self
|
||||
|
||||
# 410| self
|
||||
#-----| -> value
|
||||
|
||||
# 410| self
|
||||
#-----| -> self
|
||||
|
||||
# 410| set
|
||||
#-----| -> self
|
||||
|
||||
# 410| value
|
||||
#-----| -> self
|
||||
|
||||
# 410| yield ...
|
||||
#-----| -> exit _modify (normal)
|
||||
@@ -5318,16 +5578,19 @@ cfg.swift:
|
||||
#-----| -> self
|
||||
|
||||
# 417| self
|
||||
#-----| -> self
|
||||
|
||||
# 417| self
|
||||
#-----| -> value
|
||||
|
||||
# 417| self
|
||||
#-----| -> self
|
||||
|
||||
# 417| set
|
||||
#-----| -> self
|
||||
|
||||
# 417| value
|
||||
#-----| -> self
|
||||
|
||||
# 417| yield ...
|
||||
#-----| -> exit _modify (normal)
|
||||
@@ -5410,16 +5673,19 @@ cfg.swift:
|
||||
#-----| -> self
|
||||
|
||||
# 446| self
|
||||
#-----| -> self
|
||||
|
||||
# 446| self
|
||||
#-----| -> value
|
||||
|
||||
# 446| self
|
||||
#-----| -> self
|
||||
|
||||
# 446| set
|
||||
#-----| -> self
|
||||
|
||||
# 446| value
|
||||
#-----| -> self
|
||||
|
||||
# 446| yield ...
|
||||
#-----| -> exit _modify (normal)
|
||||
@@ -5455,16 +5721,19 @@ cfg.swift:
|
||||
#-----| -> self
|
||||
|
||||
# 450| self
|
||||
#-----| -> self
|
||||
|
||||
# 450| self
|
||||
#-----| -> value
|
||||
|
||||
# 450| self
|
||||
#-----| -> self
|
||||
|
||||
# 450| set
|
||||
#-----| -> self
|
||||
|
||||
# 450| value
|
||||
#-----| -> self
|
||||
|
||||
# 450| yield ...
|
||||
#-----| -> exit _modify (normal)
|
||||
@@ -5500,16 +5769,19 @@ cfg.swift:
|
||||
#-----| -> self
|
||||
|
||||
# 451| self
|
||||
#-----| -> self
|
||||
|
||||
# 451| self
|
||||
#-----| -> value
|
||||
|
||||
# 451| self
|
||||
#-----| -> self
|
||||
|
||||
# 451| set
|
||||
#-----| -> self
|
||||
|
||||
# 451| value
|
||||
#-----| -> self
|
||||
|
||||
# 451| yield ...
|
||||
#-----| -> exit _modify (normal)
|
||||
@@ -5545,16 +5817,19 @@ cfg.swift:
|
||||
#-----| -> self
|
||||
|
||||
# 452| self
|
||||
#-----| -> self
|
||||
|
||||
# 452| self
|
||||
#-----| -> value
|
||||
|
||||
# 452| self
|
||||
#-----| -> self
|
||||
|
||||
# 452| set
|
||||
#-----| -> self
|
||||
|
||||
# 452| value
|
||||
#-----| -> self
|
||||
|
||||
# 452| yield ...
|
||||
#-----| -> exit _modify (normal)
|
||||
@@ -5687,6 +5962,7 @@ cfg.swift:
|
||||
#-----| -> KeyPathComponent
|
||||
|
||||
# 459| KeyPathComponent
|
||||
#-----| -> KeyPathComponent
|
||||
|
||||
# 461| var ... = ...
|
||||
#-----| -> apply_kpGet_bs_0_x
|
||||
@@ -6132,6 +6408,7 @@ cfg.swift:
|
||||
#-----| -> ....(_:_:)
|
||||
|
||||
# 526| call to makeIterator()
|
||||
#-----| -> var ... = ...
|
||||
|
||||
# 526| ....(_:_:)
|
||||
#-----| -> Int.Type
|
||||
@@ -6173,6 +6450,7 @@ cfg.swift:
|
||||
#-----| -> $i$generator
|
||||
|
||||
# 533| call to next()
|
||||
#-----| -> await ...
|
||||
|
||||
# 533| for ... in ... { ... }
|
||||
#-----| empty -> exit testAsyncFor() (normal)
|
||||
@@ -6191,6 +6469,7 @@ cfg.swift:
|
||||
#-----| -> stream
|
||||
|
||||
# 533| call to makeAsyncIterator()
|
||||
#-----| -> var ... = ...
|
||||
|
||||
# 533| stream
|
||||
#-----| -> (AsyncStream<Int>) ...
|
||||
|
||||
@@ -9,7 +9,7 @@ import codeql.swift.controlflow.internal.ControlFlowGraphImpl::TestOutput
|
||||
class MyRelevantNode extends RelevantNode {
|
||||
MyRelevantNode() { this.getScope().getLocation().getFile().getName().matches("%swift/ql/test%") }
|
||||
|
||||
private AstNode asAstNode() { result = this.getNode().asAstNode() }
|
||||
private AstNode asAstNode() { result = this.getAstNode().asAstNode() }
|
||||
|
||||
override string getOrderDisambiguation() {
|
||||
result = this.asAstNode().getPrimaryQlClasses()
|
||||
|
||||
Reference in New Issue
Block a user