@@ -21,7 +21,39 @@ module Ssa {
2121
2222 class ExitBasicBlock = BasicBlocks:: ExitBasicBlock ;
2323
24- class SourceVariable = VarDecl ;
24+ private newtype TSourceVariable =
25+ TNormalSourceVariable ( VarDecl v ) or
26+ TKeyPathSourceVariable ( EntryNode entry ) { entry .getScope ( ) instanceof KeyPathExpr }
27+
28+ abstract class SourceVariable extends TSourceVariable {
29+ abstract string toString ( ) ;
30+
31+ VarDecl asVarDecl ( ) { none ( ) }
32+
33+ EntryNode asKeyPath ( ) { none ( ) }
34+
35+ DeclRefExpr getAnAccess ( ) { result .getDecl ( ) = this .asVarDecl ( ) }
36+ }
37+
38+ private class NormalSourceVariable extends SourceVariable , TNormalSourceVariable {
39+ VarDecl v ;
40+
41+ NormalSourceVariable ( ) { this = TNormalSourceVariable ( v ) }
42+
43+ override string toString ( ) { result = v .toString ( ) }
44+
45+ override VarDecl asVarDecl ( ) { result = v }
46+ }
47+
48+ private class KeyPathSourceVariable extends SourceVariable , TKeyPathSourceVariable {
49+ EntryNode enter ;
50+
51+ KeyPathSourceVariable ( ) { this = TKeyPathSourceVariable ( enter ) }
52+
53+ override string toString ( ) { result = enter .toString ( ) }
54+
55+ override EntryNode asKeyPath ( ) { result = enter }
56+ }
2557
2658 predicate variableWrite ( BasicBlock bb , int i , SourceVariable v , boolean certain ) {
2759 exists ( AssignExpr assign |
@@ -40,17 +72,22 @@ module Ssa {
4072 // ```
4173 exists ( NamedPattern pattern |
4274 bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = pattern and
43- v = pattern .getVarDecl ( ) and
75+ v . asVarDecl ( ) = pattern .getVarDecl ( ) and
4476 certain = true
4577 )
4678 or
47- v instanceof ParamDecl and
48- bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = v and
79+ exists ( ParamDecl p |
80+ p = v .asVarDecl ( ) and
81+ bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = p and
82+ certain = true
83+ )
84+ or
85+ bb .getNode ( i ) = v .asKeyPath ( ) and
4986 certain = true
5087 or
5188 // Mark the subexpression as a write of the local variable declared in the `TapExpr`.
5289 exists ( TapExpr tap |
53- v = tap .getVar ( ) and
90+ v . asVarDecl ( ) = tap .getVar ( ) and
5491 bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = tap .getSubExpr ( ) and
5592 certain = true
5693 )
@@ -60,7 +97,7 @@ module Ssa {
6097 exists ( DeclRefExpr ref |
6198 not isLValue ( ref ) and
6299 bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = ref and
63- v = ref .getDecl ( ) and
100+ v . asVarDecl ( ) = ref .getDecl ( ) and
64101 certain = true
65102 )
66103 or
@@ -71,24 +108,26 @@ module Ssa {
71108 )
72109 or
73110 exists ( ExitNode exit , AbstractFunctionDecl func |
74- func .getAParam ( ) = v or func .getSelfParam ( ) = v
75- |
111+ [ func .getAParam ( ) , func .getSelfParam ( ) ] = v .asVarDecl ( ) and
76112 bb .getNode ( i ) = exit and
77- modifiableParam ( v ) and
113+ modifiableParam ( v . asVarDecl ( ) ) and
78114 bb .getScope ( ) = func and
79115 certain = true
80116 )
81117 or
82118 // Mark the `TapExpr` as a read of the of the local variable.
83119 exists ( TapExpr tap |
84- v = tap .getVar ( ) and
120+ v . asVarDecl ( ) = tap .getVar ( ) and
85121 bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = tap and
86122 certain = true
87123 )
88124 }
89125 }
90126
91- private module SsaImpl = SsaImplCommon:: Make< SsaInput > ;
127+ /**
128+ * INTERNAL: Do not use.
129+ */
130+ module SsaImpl = SsaImplCommon:: Make< SsaInput > ;
92131
93132 cached
94133 class Definition extends SsaImpl:: Definition {
@@ -97,7 +136,7 @@ module Ssa {
97136
98137 cached
99138 ControlFlowNode getARead ( ) {
100- exists ( VarDecl v , SsaInput:: BasicBlock bb , int i |
139+ exists ( SsaInput :: SourceVariable v , SsaInput:: BasicBlock bb , int i |
101140 SsaImpl:: ssaDefReachesRead ( v , this , bb , i ) and
102141 SsaInput:: variableRead ( bb , i , v , true ) and
103142 result = bb .getNode ( i )
0 commit comments