Skip to content

Commit ea1b8a3

Browse files
committed
C++: Implement 'getAnUltimateDefinition' on SSA definitions.
1 parent 5f0efc1 commit ea1b8a3

File tree

1 file changed

+41
-1
lines changed

1 file changed

+41
-1
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,16 @@ module SsaCached {
10361036
) {
10371037
SsaImpl::lastRefRedefExt(def, sv, bb, i, next)
10381038
}
1039+
1040+
cached
1041+
Definition phiHasInputFromBlock(PhiNode phi, IRBlock bb) {
1042+
SsaImpl::phiHasInputFromBlock(phi, result, bb)
1043+
}
1044+
1045+
cached
1046+
predicate ssaDefReachesRead(SourceVariable v, Definition def, IRBlock bb, int i) {
1047+
SsaImpl::ssaDefReachesRead(v, def, bb, i)
1048+
}
10391049
}
10401050

10411051
cached
@@ -1104,6 +1114,12 @@ abstract class Def extends SsaDef, TDef {
11041114
* instead of the other way around.
11051115
*/
11061116
abstract int getIndirection();
1117+
1118+
/**
1119+
* Gets a definition that ultimately defines this SSA definition and is not
1120+
* itself a phi node.
1121+
*/
1122+
Def getAnUltimateDefinition() { result.asDef() = def.getAnUltimateDefinition() }
11071123
}
11081124

11091125
private predicate isGlobal(DefinitionExt def, GlobalDefImpl global) {
@@ -1182,6 +1198,10 @@ class Phi extends TPhi, SsaDef {
11821198
override string toString() { result = "Phi" }
11831199

11841200
SsaPhiNode getNode() { result.getPhiNode() = phi }
1201+
1202+
predicate hasInputFromBlock(Definition inp, IRBlock bb) { inp = phiHasInputFromBlock(phi, bb) }
1203+
1204+
final Definition getAnInput() { this.hasInputFromBlock(result, _) }
11851205
}
11861206

11871207
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
@@ -1204,9 +1224,29 @@ class PhiNode extends SsaImpl::DefinitionExt {
12041224
* on reads instead of writes.
12051225
*/
12061226
predicate isPhiRead() { this instanceof SsaImpl::PhiReadNode }
1227+
1228+
/** Holds if `inp` is an input to this phi node along the edge originating in `bb`. */
1229+
predicate hasInputFromBlock(Definition inp, IRBlock bb) {
1230+
inp = SsaCached::phiHasInputFromBlock(this, bb)
1231+
}
1232+
1233+
/** Gets a definition that is an input to this phi node. */
1234+
final Definition getAnInput() { this.hasInputFromBlock(result, _) }
12071235
}
12081236

1209-
class DefinitionExt = SsaImpl::DefinitionExt;
1237+
/** An static single assignment (SSA) definition. */
1238+
class DefinitionExt extends SsaImpl::DefinitionExt {
1239+
private Definition getAPhiInputOrPriorDefinition() { result = this.(PhiNode).getAnInput() }
1240+
1241+
/**
1242+
* Gets a definition that ultimately defines this SSA definition and is
1243+
* not itself a phi node.
1244+
*/
1245+
final DefinitionExt getAnUltimateDefinition() {
1246+
result = this.getAPhiInputOrPriorDefinition*() and
1247+
not result instanceof PhiNode
1248+
}
1249+
}
12101250

12111251
class Definition = SsaImpl::Definition;
12121252

0 commit comments

Comments
 (0)