@@ -2,55 +2,131 @@ cached
22module Ssa {
33 private import swift
44 private import internal.SsaImplCommon as SsaImplCommon
5- private import internal.SsaImplSpecific as SsaImplSpecific
65 private import codeql.swift.controlflow.CfgNodes
76 private import codeql.swift.controlflow.ControlFlowGraph
8- private import codeql.swift.controlflow.BasicBlocks
7+ private import codeql.swift.controlflow.BasicBlocks as BasicBlocks
8+
9+ private module SsaInput implements SsaImplCommon:: InputSig {
10+ private import internal.DataFlowPrivate
11+ private import codeql.swift.controlflow.ControlFlowGraph
12+ private import codeql.swift.controlflow.CfgNodes
13+
14+ class BasicBlock = BasicBlocks:: BasicBlock ;
15+
16+ BasicBlock getImmediateBasicBlockDominator ( BasicBlock bb ) {
17+ result = bb .getImmediateDominator ( )
18+ }
19+
20+ BasicBlock getABasicBlockSuccessor ( BasicBlock bb ) { result = bb .getASuccessor ( ) }
21+
22+ class ExitBasicBlock = BasicBlocks:: ExitBasicBlock ;
23+
24+ class SourceVariable = VarDecl ;
25+
26+ predicate variableWrite ( BasicBlock bb , int i , SourceVariable v , boolean certain ) {
27+ exists ( AssignExpr assign |
28+ bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = assign and
29+ assign .getDest ( ) = v .getAnAccess ( ) and
30+ certain = true
31+ )
32+ or
33+ exists ( PatternBindingDecl decl , Pattern pattern |
34+ bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = pattern and
35+ decl .getAPattern ( ) = pattern and
36+ v .getParentPattern ( ) = pattern and
37+ certain = true
38+ )
39+ or
40+ v instanceof ParamDecl and
41+ bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = v and
42+ certain = true
43+ or
44+ // Mark the subexpression as a write of the local variable declared in the `TapExpr`.
45+ exists ( TapExpr tap |
46+ v = tap .getVar ( ) and
47+ bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = tap .getSubExpr ( ) and
48+ certain = true
49+ )
50+ }
51+
52+ predicate variableRead ( BasicBlock bb , int i , SourceVariable v , boolean certain ) {
53+ exists ( DeclRefExpr ref |
54+ not isLValue ( ref ) and
55+ bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = ref and
56+ v = ref .getDecl ( ) and
57+ certain = true
58+ )
59+ or
60+ exists ( InOutExpr expr |
61+ bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = expr and
62+ expr .getSubExpr ( ) = v .getAnAccess ( ) and
63+ certain = true
64+ )
65+ or
66+ exists ( ExitNode exit , AbstractFunctionDecl func |
67+ func .getAParam ( ) = v or func .getSelfParam ( ) = v
68+ |
69+ bb .getNode ( i ) = exit and
70+ modifiableParam ( v ) and
71+ bb .getScope ( ) = func and
72+ certain = true
73+ )
74+ or
75+ // Mark the `TapExpr` as a read of the of the local variable.
76+ exists ( TapExpr tap |
77+ v = tap .getVar ( ) and
78+ bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = tap and
79+ certain = true
80+ )
81+ }
82+ }
83+
84+ private module SsaImpl = SsaImplCommon:: Make< SsaInput > ;
985
1086 cached
11- class Definition extends SsaImplCommon :: Definition {
87+ class Definition extends SsaImpl :: Definition {
1288 cached
1389 Location getLocation ( ) { none ( ) }
1490
1591 cached
1692 ControlFlowNode getARead ( ) {
17- exists ( VarDecl v , BasicBlock bb , int i |
18- SsaImplCommon :: ssaDefReachesRead ( v , this , bb , i ) and
19- SsaImplSpecific :: variableRead ( bb , i , v , true ) and
93+ exists ( VarDecl v , SsaInput :: BasicBlock bb , int i |
94+ SsaImpl :: ssaDefReachesRead ( v , this , bb , i ) and
95+ SsaInput :: variableRead ( bb , i , v , true ) and
2096 result = bb .getNode ( i )
2197 )
2298 }
2399
24100 cached
25101 ControlFlowNode getAFirstRead ( ) {
26- exists ( BasicBlock bb1 , int i1 , BasicBlock bb2 , int i2 |
102+ exists ( SsaInput :: BasicBlock bb1 , int i1 , SsaInput :: BasicBlock bb2 , int i2 |
27103 this .definesAt ( _, bb1 , i1 ) and
28- SsaImplCommon :: adjacentDefNoUncertainReads ( this , bb1 , i1 , bb2 , i2 ) and
104+ SsaImpl :: adjacentDefNoUncertainReads ( this , bb1 , i1 , bb2 , i2 ) and
29105 result = bb2 .getNode ( i2 )
30106 )
31107 }
32108
33109 cached
34110 predicate adjacentReadPair ( ControlFlowNode read1 , ControlFlowNode read2 ) {
35- exists ( BasicBlock bb1 , int i1 , BasicBlock bb2 , int i2 |
111+ exists ( SsaInput :: BasicBlock bb1 , int i1 , SsaInput :: BasicBlock bb2 , int i2 |
36112 read1 = bb1 .getNode ( i1 ) and
37- SsaImplSpecific :: variableRead ( bb1 , i1 , _, true ) and
38- SsaImplCommon :: adjacentDefNoUncertainReads ( this , bb1 , i1 , bb2 , i2 ) and
113+ SsaInput :: variableRead ( bb1 , i1 , _, true ) and
114+ SsaImpl :: adjacentDefNoUncertainReads ( this , bb1 , i1 , bb2 , i2 ) and
39115 read2 = bb2 .getNode ( i2 )
40116 )
41117 }
42118
43119 cached
44- predicate lastRefRedef ( BasicBlock bb , int i , Definition next ) {
45- SsaImplCommon :: lastRefRedef ( this , bb , i , next )
120+ predicate lastRefRedef ( SsaInput :: BasicBlock bb , int i , Definition next ) {
121+ SsaImpl :: lastRefRedef ( this , bb , i , next )
46122 }
47123 }
48124
49125 cached
50- class WriteDefinition extends Definition , SsaImplCommon :: WriteDefinition {
126+ class WriteDefinition extends Definition , SsaImpl :: WriteDefinition {
51127 cached
52128 override Location getLocation ( ) {
53- exists ( BasicBlock bb , int i |
129+ exists ( SsaInput :: BasicBlock bb , int i |
54130 this .definesAt ( _, bb , i ) and
55131 result = bb .getNode ( i ) .getLocation ( )
56132 )
@@ -63,14 +139,16 @@ module Ssa {
63139 cached
64140 predicate assigns ( CfgNode value ) {
65141 exists (
66- AssignExpr a , BasicBlock bb , int i // TODO: use CFG node for assignment expr
142+ AssignExpr a , SsaInput :: BasicBlock bb , int i // TODO: use CFG node for assignment expr
67143 |
68144 this .definesAt ( _, bb , i ) and
69145 a = bb .getNode ( i ) .getNode ( ) .asAstNode ( ) and
70146 value .getNode ( ) .asAstNode ( ) = a .getSource ( )
71147 )
72148 or
73- exists ( VarDecl var , BasicBlock bb , int blockIndex , PatternBindingDecl pbd , Expr init |
149+ exists (
150+ VarDecl var , SsaInput:: BasicBlock bb , int blockIndex , PatternBindingDecl pbd , Expr init
151+ |
74152 this .definesAt ( var , bb , blockIndex ) and
75153 pbd .getAPattern ( ) = bb .getNode ( blockIndex ) .getNode ( ) .asAstNode ( ) and
76154 init = var .getParentInitializer ( )
@@ -84,17 +162,19 @@ module Ssa {
84162 }
85163
86164 cached
87- class PhiDefinition extends Definition , SsaImplCommon :: PhiNode {
165+ class PhiDefinition extends Definition , SsaImpl :: PhiNode {
88166 cached
89167 override Location getLocation ( ) {
90- exists ( BasicBlock bb , int i |
168+ exists ( SsaInput :: BasicBlock bb , int i |
91169 this .definesAt ( _, bb , i ) and
92170 result = bb .getLocation ( )
93171 )
94172 }
95173
96174 cached
97- Definition getPhiInput ( BasicBlock bb ) { SsaImplCommon:: phiHasInputFromBlock ( this , result , bb ) }
175+ Definition getPhiInput ( SsaInput:: BasicBlock bb ) {
176+ SsaImpl:: phiHasInputFromBlock ( this , result , bb )
177+ }
98178
99179 cached
100180 Definition getAPhiInput ( ) { result = this .getPhiInput ( _) }
0 commit comments