@@ -3,6 +3,8 @@ private import DataFlowPublic
33private import DataFlowDispatch
44private import codeql.swift.controlflow.CfgNodes
55private import codeql.swift.dataflow.Ssa
6+ private import codeql.swift.controlflow.BasicBlocks
7+ private import codeql.swift.dataflow.internal.SsaImplCommon as SsaImpl
68
79/** Gets the callable in which this node occurs. */
810DataFlowCallable nodeGetEnclosingCallable ( NodeImpl n ) { result = n .getEnclosingCallable ( ) }
@@ -31,12 +33,25 @@ private class ExprNodeImpl extends ExprNode, NodeImpl {
3133 override Location getLocationImpl ( ) { result = expr .getLocation ( ) }
3234
3335 override string toStringImpl ( ) { result = expr .toString ( ) }
36+
37+ override DataFlowCallable getEnclosingCallable ( ) { result = TDataFlowFunc ( expr .getScope ( ) ) }
3438}
3539
3640private class SsaDefinitionNodeImpl extends SsaDefinitionNode , NodeImpl {
3741 override Location getLocationImpl ( ) { result = def .getLocation ( ) }
3842
3943 override string toStringImpl ( ) { result = def .toString ( ) }
44+
45+ override DataFlowCallable getEnclosingCallable ( ) {
46+ result = TDataFlowFunc ( def .getBasicBlock ( ) .getScope ( ) )
47+ }
48+ }
49+
50+ private predicate localFlowSsaInput ( Node nodeFrom , Ssa:: Definition def , Ssa:: Definition next ) {
51+ exists ( BasicBlock bb , int i | SsaImpl:: lastRefRedef ( def , bb , i , next ) |
52+ def .definesAt ( _, bb , i ) and
53+ def = nodeFrom .asDefinition ( )
54+ )
4055}
4156
4257/** A collection of cached types and predicates to be evaluated in the same stage. */
@@ -45,7 +60,6 @@ private module Cached {
4560 cached
4661 newtype TNode =
4762 TExprNode ( ExprCfgNode e ) or
48- TNormalParameterNode ( ParamDecl p ) or
4963 TSsaDefinitionNode ( Ssa:: Definition def )
5064
5165 private predicate localFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
@@ -60,6 +74,9 @@ private module Cached {
6074 or
6175 // use-use flow
6276 def .adjacentReadPair ( nodeFrom .getCfgNode ( ) , nodeTo .getCfgNode ( ) )
77+ or
78+ // step from previous read to Phi node
79+ localFlowSsaInput ( nodeFrom , def , nodeTo .asDefinition ( ) )
6380 )
6481 }
6582
@@ -93,18 +110,29 @@ private module ParameterNodes {
93110 predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) { none ( ) }
94111 }
95112
96- class NormalParameterNode extends ParameterNodeImpl , TNormalParameterNode {
113+ class NormalParameterNode extends ParameterNodeImpl , SsaDefinitionNode {
97114 ParamDecl param ;
98115
99- NormalParameterNode ( ) { this = TNormalParameterNode ( param ) }
116+ NormalParameterNode ( ) {
117+ exists ( BasicBlock bb , int i |
118+ super .asDefinition ( ) .definesAt ( param , bb , i ) and
119+ bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = param
120+ )
121+ }
100122
101123 override Location getLocationImpl ( ) { result = param .getLocation ( ) }
102124
103125 override string toStringImpl ( ) { result = param .toString ( ) }
104126
105127 override predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) {
106- none ( ) // TODO
128+ exists ( FuncDecl f , int index |
129+ c = TDataFlowFunc ( f ) and
130+ f .getParam ( index ) = param and
131+ pos = TPositionalParameter ( index )
132+ )
107133 }
134+
135+ override DataFlowCallable getEnclosingCallable ( ) { isParameterOf ( result , _) }
108136 }
109137}
110138
@@ -119,7 +147,16 @@ abstract class ArgumentNode extends Node {
119147 final DataFlowCall getCall ( ) { this .argumentOf ( result , _) }
120148}
121149
122- private module ArgumentNodes { }
150+ private module ArgumentNodes {
151+ class NormalArgumentNode extends ExprNode , ArgumentNode {
152+ NormalArgumentNode ( ) { exists ( CallExpr call | call .getAnArgument ( ) .getExpr ( ) = this .asExpr ( ) ) }
153+
154+ override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
155+ call .asExpr ( ) .( CallExpr ) .getArgument ( pos .( PositionalArgumentPosition ) .getIndex ( ) ) .getExpr ( ) =
156+ this .asExpr ( )
157+ }
158+ }
159+ }
123160
124161import ArgumentNodes
125162
@@ -129,7 +166,13 @@ abstract class ReturnNode extends Node {
129166 abstract ReturnKind getKind ( ) ;
130167}
131168
132- private module ReturnNodes { }
169+ private module ReturnNodes {
170+ class ReturnReturnNode extends ReturnNode , ExprNode {
171+ ReturnReturnNode ( ) { exists ( ReturnStmt stmt | stmt .getResult ( ) = this .asExpr ( ) ) }
172+
173+ override ReturnKind getKind ( ) { result instanceof NormalReturnKind }
174+ }
175+ }
133176
134177import ReturnNodes
135178
@@ -139,7 +182,13 @@ abstract class OutNode extends Node {
139182 abstract DataFlowCall getCall ( ReturnKind kind ) ;
140183}
141184
142- private module OutNodes { }
185+ private module OutNodes {
186+ class CallOutNode extends OutNode , DataFlowCall {
187+ override DataFlowCall getCall ( ReturnKind kind ) {
188+ result = this and kind instanceof NormalReturnKind
189+ }
190+ }
191+ }
143192
144193import OutNodes
145194
@@ -169,7 +218,9 @@ class DataFlowType extends TDataFlowType {
169218}
170219
171220/** Gets the type of `n` used for type pruning. */
172- DataFlowType getNodeType ( NodeImpl n ) { none ( ) }
221+ DataFlowType getNodeType ( NodeImpl n ) {
222+ any ( ) // return the singleton DataFlowType until we support type pruning for Swift
223+ }
173224
174225/** Gets a string representation of a `DataFlowType`. */
175226string ppReprType ( DataFlowType t ) { result = t .toString ( ) }
0 commit comments