1- import SsaImplCommon
21private import cpp as Cpp
32private import semmle.code.cpp.ir.IR
43private import DataFlowUtil
54private import DataFlowImplCommon as DataFlowImplCommon
65private import semmle.code.cpp.models.interfaces.Allocation as Alloc
76private import semmle.code.cpp.models.interfaces.DataFlow as DataFlow
7+ private import SsaImplCommon as SsaImplCommon
88
99private module SourceVariables {
1010 private newtype TSourceVariable =
@@ -38,8 +38,6 @@ private module SourceVariables {
3838 }
3939}
4040
41- import SourceVariables
42-
4341cached
4442private newtype TDefOrUse =
4543 TExplicitDef ( Instruction store ) { explicitWrite ( _, store , _) } or
@@ -86,7 +84,7 @@ abstract class Def extends DefOrUse {
8684 Instruction getInstruction ( ) { result = store }
8785
8886 /** Gets the variable that is defined by this definition. */
89- abstract SourceVariable getSourceVariable ( ) ;
87+ abstract SourceVariables :: SourceVariable getSourceVariable ( ) ;
9088
9189 /** Holds if this definition is guaranteed to happen. */
9290 abstract predicate isCertain ( ) ;
@@ -103,10 +101,10 @@ abstract class Def extends DefOrUse {
103101private class ExplicitDef extends Def , TExplicitDef {
104102 ExplicitDef ( ) { this = TExplicitDef ( store ) }
105103
106- override SourceVariable getSourceVariable ( ) {
104+ override SourceVariables :: SourceVariable getSourceVariable ( ) {
107105 exists ( VariableInstruction var |
108106 explicitWrite ( _, this .getInstruction ( ) , var ) and
109- result .( SourceIRVariable ) .getIRVariable ( ) = var .getIRVariable ( )
107+ result .( SourceVariables :: SourceIRVariable ) .getIRVariable ( ) = var .getIRVariable ( )
110108 )
111109 }
112110
@@ -116,11 +114,11 @@ private class ExplicitDef extends Def, TExplicitDef {
116114private class ParameterDef extends Def , TInitializeParam {
117115 ParameterDef ( ) { this = TInitializeParam ( store ) }
118116
119- override SourceVariable getSourceVariable ( ) {
120- result .( SourceIRVariable ) .getIRVariable ( ) =
117+ override SourceVariables :: SourceVariable getSourceVariable ( ) {
118+ result .( SourceVariables :: SourceIRVariable ) .getIRVariable ( ) =
121119 store .( InitializeParameterInstruction ) .getIRVariable ( )
122120 or
123- result .( SourceIRVariableIndirection ) .getUnderlyingIRVariable ( ) =
121+ result .( SourceVariables :: SourceIRVariableIndirection ) .getUnderlyingIRVariable ( ) =
124122 store .( InitializeIndirectionInstruction ) .getIRVariable ( )
125123 }
126124
@@ -138,7 +136,7 @@ abstract class Use extends DefOrUse {
138136 override string toString ( ) { result = "Use" }
139137
140138 /** Gets the variable that is used by this use. */
141- abstract SourceVariable getSourceVariable ( ) ;
139+ abstract SourceVariables :: SourceVariable getSourceVariable ( ) ;
142140
143141 override IRBlock getBlock ( ) { result = use .getUse ( ) .getBlock ( ) }
144142
@@ -148,23 +146,26 @@ abstract class Use extends DefOrUse {
148146private class ExplicitUse extends Use , TExplicitUse {
149147 ExplicitUse ( ) { this = TExplicitUse ( use ) }
150148
151- override SourceVariable getSourceVariable ( ) {
149+ override SourceVariables :: SourceVariable getSourceVariable ( ) {
152150 exists ( VariableInstruction var |
153151 use .getDef ( ) = var and
154152 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 ( )
157157 )
158158 }
159159}
160160
161161private class ReturnParameterIndirection extends Use , TReturnParamIndirection {
162162 ReturnParameterIndirection ( ) { this = TReturnParamIndirection ( use ) }
163163
164- override SourceVariable getSourceVariable ( ) {
164+ override SourceVariables :: SourceVariable getSourceVariable ( ) {
165165 exists ( ReturnIndirectionInstruction ret |
166166 returnParameterIndirection ( use , ret ) and
167- result .( SourceIRVariableIndirection ) .getUnderlyingIRVariable ( ) = ret .getIRVariable ( )
167+ result .( SourceVariables:: SourceIRVariableIndirection ) .getUnderlyingIRVariable ( ) =
168+ ret .getIRVariable ( )
168169 )
169170 }
170171}
@@ -610,27 +611,45 @@ private module Cached {
610611
611612import Cached
612613
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
625616
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+ }
636653}
654+
655+ import SsaImplCommon:: Make< SsaInput >
0 commit comments