1
- import SsaImplCommon
2
1
private import cpp as Cpp
3
2
private import semmle.code.cpp.ir.IR
4
3
private import DataFlowUtil
5
4
private import DataFlowImplCommon as DataFlowImplCommon
6
5
private import semmle.code.cpp.models.interfaces.Allocation as Alloc
7
6
private import semmle.code.cpp.models.interfaces.DataFlow as DataFlow
7
+ private import SsaImplCommon as SsaImplCommon
8
8
9
9
private module SourceVariables {
10
10
private newtype TSourceVariable =
@@ -38,8 +38,6 @@ private module SourceVariables {
38
38
}
39
39
}
40
40
41
- import SourceVariables
42
-
43
41
cached
44
42
private newtype TDefOrUse =
45
43
TExplicitDef ( Instruction store ) { explicitWrite ( _, store , _) } or
@@ -86,7 +84,7 @@ abstract class Def extends DefOrUse {
86
84
Instruction getInstruction ( ) { result = store }
87
85
88
86
/** Gets the variable that is defined by this definition. */
89
- abstract SourceVariable getSourceVariable ( ) ;
87
+ abstract SourceVariables :: SourceVariable getSourceVariable ( ) ;
90
88
91
89
/** Holds if this definition is guaranteed to happen. */
92
90
abstract predicate isCertain ( ) ;
@@ -103,10 +101,10 @@ abstract class Def extends DefOrUse {
103
101
private class ExplicitDef extends Def , TExplicitDef {
104
102
ExplicitDef ( ) { this = TExplicitDef ( store ) }
105
103
106
- override SourceVariable getSourceVariable ( ) {
104
+ override SourceVariables :: SourceVariable getSourceVariable ( ) {
107
105
exists ( VariableInstruction var |
108
106
explicitWrite ( _, this .getInstruction ( ) , var ) and
109
- result .( SourceIRVariable ) .getIRVariable ( ) = var .getIRVariable ( )
107
+ result .( SourceVariables :: SourceIRVariable ) .getIRVariable ( ) = var .getIRVariable ( )
110
108
)
111
109
}
112
110
@@ -116,11 +114,11 @@ private class ExplicitDef extends Def, TExplicitDef {
116
114
private class ParameterDef extends Def , TInitializeParam {
117
115
ParameterDef ( ) { this = TInitializeParam ( store ) }
118
116
119
- override SourceVariable getSourceVariable ( ) {
120
- result .( SourceIRVariable ) .getIRVariable ( ) =
117
+ override SourceVariables :: SourceVariable getSourceVariable ( ) {
118
+ result .( SourceVariables :: SourceIRVariable ) .getIRVariable ( ) =
121
119
store .( InitializeParameterInstruction ) .getIRVariable ( )
122
120
or
123
- result .( SourceIRVariableIndirection ) .getUnderlyingIRVariable ( ) =
121
+ result .( SourceVariables :: SourceIRVariableIndirection ) .getUnderlyingIRVariable ( ) =
124
122
store .( InitializeIndirectionInstruction ) .getIRVariable ( )
125
123
}
126
124
@@ -138,7 +136,7 @@ abstract class Use extends DefOrUse {
138
136
override string toString ( ) { result = "Use" }
139
137
140
138
/** Gets the variable that is used by this use. */
141
- abstract SourceVariable getSourceVariable ( ) ;
139
+ abstract SourceVariables :: SourceVariable getSourceVariable ( ) ;
142
140
143
141
override IRBlock getBlock ( ) { result = use .getUse ( ) .getBlock ( ) }
144
142
@@ -148,23 +146,26 @@ abstract class Use extends DefOrUse {
148
146
private class ExplicitUse extends Use , TExplicitUse {
149
147
ExplicitUse ( ) { this = TExplicitUse ( use ) }
150
148
151
- override SourceVariable getSourceVariable ( ) {
149
+ override SourceVariables :: SourceVariable getSourceVariable ( ) {
152
150
exists ( VariableInstruction var |
153
151
use .getDef ( ) = var and
154
152
if use .getUse ( ) instanceof ReadSideEffectInstruction
155
- then result .( SourceIRVariableIndirection ) .getUnderlyingIRVariable ( ) = var .getIRVariable ( )
156
- else result .( SourceIRVariable ) .getIRVariable ( ) = var .getIRVariable ( )
153
+ then
154
+ result .( SourceVariables:: SourceIRVariableIndirection ) .getUnderlyingIRVariable ( ) =
155
+ var .getIRVariable ( )
156
+ else result .( SourceVariables:: SourceIRVariable ) .getIRVariable ( ) = var .getIRVariable ( )
157
157
)
158
158
}
159
159
}
160
160
161
161
private class ReturnParameterIndirection extends Use , TReturnParamIndirection {
162
162
ReturnParameterIndirection ( ) { this = TReturnParamIndirection ( use ) }
163
163
164
- override SourceVariable getSourceVariable ( ) {
164
+ override SourceVariables :: SourceVariable getSourceVariable ( ) {
165
165
exists ( ReturnIndirectionInstruction ret |
166
166
returnParameterIndirection ( use , ret ) and
167
- result .( SourceIRVariableIndirection ) .getUnderlyingIRVariable ( ) = ret .getIRVariable ( )
167
+ result .( SourceVariables:: SourceIRVariableIndirection ) .getUnderlyingIRVariable ( ) =
168
+ ret .getIRVariable ( )
168
169
)
169
170
}
170
171
}
@@ -610,27 +611,45 @@ private module Cached {
610
611
611
612
import Cached
612
613
613
- /**
614
- * Holds if the `i`'th write in block `bb` writes to the variable `v`.
615
- * `certain` is `true` if the write is guaranteed to overwrite the entire variable.
616
- */
617
- predicate variableWrite ( IRBlock bb , int i , SourceVariable v , boolean certain ) {
618
- DataFlowImplCommon:: forceCachingInSameStage ( ) and
619
- exists ( Def def |
620
- def .hasIndexInBlock ( bb , i ) and
621
- v = def .getSourceVariable ( ) and
622
- ( if def .isCertain ( ) then certain = true else certain = false )
623
- )
624
- }
614
+ private module SsaInput implements SsaImplCommon:: InputSig {
615
+ private import semmle.code.cpp.ir.IR
625
616
626
- /**
627
- * Holds if the `i`'th read in block `bb` reads to the variable `v`.
628
- * `certain` is `true` if the read is guaranteed. For C++, this is always the case.
629
- */
630
- predicate variableRead ( IRBlock bb , int i , SourceVariable v , boolean certain ) {
631
- exists ( Use use |
632
- use .hasIndexInBlock ( bb , i ) and
633
- v = use .getSourceVariable ( ) and
634
- certain = true
635
- )
617
+ class BasicBlock = IRBlock ;
618
+
619
+ class SourceVariable = SourceVariables:: SourceVariable ;
620
+
621
+ BasicBlock getImmediateBasicBlockDominator ( BasicBlock bb ) { result .immediatelyDominates ( bb ) }
622
+
623
+ BasicBlock getABasicBlockSuccessor ( BasicBlock bb ) { result = bb .getASuccessor ( ) }
624
+
625
+ class ExitBasicBlock extends IRBlock {
626
+ ExitBasicBlock ( ) { this .getLastInstruction ( ) instanceof ExitFunctionInstruction }
627
+ }
628
+
629
+ /**
630
+ * Holds if the `i`'th write in block `bb` writes to the variable `v`.
631
+ * `certain` is `true` if the write is guaranteed to overwrite the entire variable.
632
+ */
633
+ predicate variableWrite ( BasicBlock bb , int i , SourceVariable v , boolean certain ) {
634
+ DataFlowImplCommon:: forceCachingInSameStage ( ) and
635
+ exists ( Def def |
636
+ def .hasIndexInBlock ( bb , i ) and
637
+ v = def .getSourceVariable ( ) and
638
+ ( if def .isCertain ( ) then certain = true else certain = false )
639
+ )
640
+ }
641
+
642
+ /**
643
+ * Holds if the `i`'th read in block `bb` reads to the variable `v`.
644
+ * `certain` is `true` if the read is guaranteed. For C++, this is always the case.
645
+ */
646
+ predicate variableRead ( BasicBlock bb , int i , SourceVariable v , boolean certain ) {
647
+ exists ( Use use |
648
+ use .hasIndexInBlock ( bb , i ) and
649
+ v = use .getSourceVariable ( ) and
650
+ certain = true
651
+ )
652
+ }
636
653
}
654
+
655
+ import SsaImplCommon:: Make< SsaInput >
0 commit comments