@@ -2,55 +2,131 @@ cached
2
2
module Ssa {
3
3
private import swift
4
4
private import internal.SsaImplCommon as SsaImplCommon
5
- private import internal.SsaImplSpecific as SsaImplSpecific
6
5
private import codeql.swift.controlflow.CfgNodes
7
6
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 > ;
9
85
10
86
cached
11
- class Definition extends SsaImplCommon :: Definition {
87
+ class Definition extends SsaImpl :: Definition {
12
88
cached
13
89
Location getLocation ( ) { none ( ) }
14
90
15
91
cached
16
92
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
20
96
result = bb .getNode ( i )
21
97
)
22
98
}
23
99
24
100
cached
25
101
ControlFlowNode getAFirstRead ( ) {
26
- exists ( BasicBlock bb1 , int i1 , BasicBlock bb2 , int i2 |
102
+ exists ( SsaInput :: BasicBlock bb1 , int i1 , SsaInput :: BasicBlock bb2 , int i2 |
27
103
this .definesAt ( _, bb1 , i1 ) and
28
- SsaImplCommon :: adjacentDefNoUncertainReads ( this , bb1 , i1 , bb2 , i2 ) and
104
+ SsaImpl :: adjacentDefNoUncertainReads ( this , bb1 , i1 , bb2 , i2 ) and
29
105
result = bb2 .getNode ( i2 )
30
106
)
31
107
}
32
108
33
109
cached
34
110
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 |
36
112
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
39
115
read2 = bb2 .getNode ( i2 )
40
116
)
41
117
}
42
118
43
119
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 )
46
122
}
47
123
}
48
124
49
125
cached
50
- class WriteDefinition extends Definition , SsaImplCommon :: WriteDefinition {
126
+ class WriteDefinition extends Definition , SsaImpl :: WriteDefinition {
51
127
cached
52
128
override Location getLocation ( ) {
53
- exists ( BasicBlock bb , int i |
129
+ exists ( SsaInput :: BasicBlock bb , int i |
54
130
this .definesAt ( _, bb , i ) and
55
131
result = bb .getNode ( i ) .getLocation ( )
56
132
)
@@ -63,14 +139,16 @@ module Ssa {
63
139
cached
64
140
predicate assigns ( CfgNode value ) {
65
141
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
67
143
|
68
144
this .definesAt ( _, bb , i ) and
69
145
a = bb .getNode ( i ) .getNode ( ) .asAstNode ( ) and
70
146
value .getNode ( ) .asAstNode ( ) = a .getSource ( )
71
147
)
72
148
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
+ |
74
152
this .definesAt ( var , bb , blockIndex ) and
75
153
pbd .getAPattern ( ) = bb .getNode ( blockIndex ) .getNode ( ) .asAstNode ( ) and
76
154
init = var .getParentInitializer ( )
@@ -84,17 +162,19 @@ module Ssa {
84
162
}
85
163
86
164
cached
87
- class PhiDefinition extends Definition , SsaImplCommon :: PhiNode {
165
+ class PhiDefinition extends Definition , SsaImpl :: PhiNode {
88
166
cached
89
167
override Location getLocation ( ) {
90
- exists ( BasicBlock bb , int i |
168
+ exists ( SsaInput :: BasicBlock bb , int i |
91
169
this .definesAt ( _, bb , i ) and
92
170
result = bb .getLocation ( )
93
171
)
94
172
}
95
173
96
174
cached
97
- Definition getPhiInput ( BasicBlock bb ) { SsaImplCommon:: phiHasInputFromBlock ( this , result , bb ) }
175
+ Definition getPhiInput ( SsaInput:: BasicBlock bb ) {
176
+ SsaImpl:: phiHasInputFromBlock ( this , result , bb )
177
+ }
98
178
99
179
cached
100
180
Definition getAPhiInput ( ) { result = this .getPhiInput ( _) }
0 commit comments