11import csharp
22
3- private cached module MiniSsa {
4- private import ControlFlowGraph
5-
6- /**
7- * Holds if the `i`th node of basic block `bb` is assignable definition `def`,
8- * targeting local scope variable `v`.
9- */
10- private predicate defAt ( BasicBlock bb , int i , AssignableDefinition def , LocalScopeVariable v ) {
11- bb .getNode ( i ) = def .getAControlFlowNode ( ) and
12- v = def .getTarget ( )
13- }
14-
15- /**
16- * Holds if basic block `bb` would need to start with a phi node for local scope
17- * variable `v` in an SSA representation.
18- */
19- private predicate needsPhiNode ( BasicBlock bb , LocalScopeVariable v ) {
20- exists ( BasicBlock def |
21- def .inDominanceFrontier ( bb ) |
22- defAt ( def , _, _, v ) or
23- needsPhiNode ( def , v )
24- )
25- }
26-
27- private newtype SsaRefKind = SsaRead ( ) or SsaDef ( )
28-
29- /**
30- * Holds if the `i`th node of basic block `bb` is a reference to `v`,
31- * either a read (when `k` is `SsaRead()`) or a write including phi nodes
32- * (when `k` is `SsaDef()`).
33- */
34- private predicate ssaRef ( BasicBlock bb , int i , LocalScopeVariable v , SsaRefKind k ) {
35- bb .getNode ( i ) .getElement ( ) = v .getAnAccess ( ) .( VariableRead ) and
36- k = SsaRead ( )
37- or
38- defAt ( bb , i , _, v ) and
39- k = SsaDef ( )
40- or
41- needsPhiNode ( bb , v ) and
42- i = - 1 and
43- k = SsaDef ( )
44- }
45-
46- /**
47- * Gets the (1-based) rank of the reference to `v` at the `i`th node of basic
48- * block `bb`, which has the given reference kind `k`.
49- */
50- private int ssaRefRank ( BasicBlock bb , int i , LocalScopeVariable v , SsaRefKind k ) {
51- i = rank [ result ] ( int j | ssaRef ( bb , j , v , _) ) and
52- ssaRef ( bb , i , v , k )
53- }
54-
55- /**
56- * Holds if definition `def` of local scope variable `v` inside basic block
57- * `bb` reaches the reference at rank `rnk`, without passing through another
58- * definition of `v`, including phi nodes.
59- */
60- private predicate defReachesRank ( BasicBlock bb , AssignableDefinition def , LocalScopeVariable v , int rnk ) {
61- exists ( int i |
62- rnk = ssaRefRank ( bb , i , v , SsaDef ( ) ) |
63- defAt ( bb , i , def , v )
64- )
65- or
66- defReachesRank ( bb , def , v , rnk - 1 ) and
67- rnk = ssaRefRank ( bb , _, v , SsaRead ( ) )
68- }
69-
70- /**
71- * Holds if definition `def` of local scope variable `v` reaches the end of
72- * basic block `bb` without passing through another definition of `v`, including
73- * phi nodes.
74- */
75- private predicate reachesEndOf ( AssignableDefinition def , LocalScopeVariable v , BasicBlock bb ) {
76- exists ( int rnk |
77- defReachesRank ( bb , def , v , rnk ) and
78- rnk = max ( ssaRefRank ( bb , _, v , _) )
79- )
80- or
81- exists ( BasicBlock mid |
82- reachesEndOf ( def , v , mid ) and
83- not exists ( ssaRefRank ( mid , _, v , SsaDef ( ) ) ) and
84- bb = mid .getASuccessor ( )
85- )
86- }
87-
88- /**
89- * Gets a read of the SSA definition for variable `v` at definition `def`. That is,
90- * a read that is guaranteed to read the value assigned at definition `def`.
91- */
92- cached AssignableRead getARead ( AssignableDefinition def , LocalScopeVariable v ) {
93- exists ( BasicBlock bb , int i , int rnk |
94- result .getTarget ( ) = v and
95- result .getAControlFlowNode ( ) = bb .getNode ( i ) and
96- rnk = ssaRefRank ( bb , i , v , SsaRead ( ) )
97- |
98- defReachesRank ( bb , def , v , rnk )
99- or
100- reachesEndOf ( def , v , bb .getAPredecessor ( ) ) and
101- not ssaRefRank ( bb , i , v , SsaDef ( ) ) < rnk
102- )
103- }
104- }
105-
1063/**
1074 * INTERNAL: Do not use.
1085 *
@@ -112,12 +9,14 @@ private cached module MiniSsa {
1129 * Instead, this library relies on a self-contained, minimalistic SSA-like
11310 * implementation.
11411 */
115- module DataFlowInternal {
12+ module Steps {
13+ private import semmle.code.csharp.dataflow.internal.BaseSSA
14+
11615 /**
11716 * Gets a read that is guaranteed to read the value assigned at definition `def`.
11817 */
11918 private AssignableRead getARead ( AssignableDefinition def ) {
120- result = MiniSsa :: getARead ( def , _)
19+ result = BaseSsa :: getARead ( def , _)
12120 or
12221 exists ( LocalScopeVariable v |
12322 def .getTarget ( ) = v |
0 commit comments