Skip to content

Commit 2f744ce

Browse files
committed
SSA: Expose module for qltesting adjacent references.
1 parent 9e03b12 commit 2f744ce

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

shared/ssa/codeql/ssa/Ssa.qll

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1954,4 +1954,85 @@ module Make<LocationSig Location, InputSig<Location> Input> {
19541954
}
19551955
}
19561956
}
1957+
1958+
/**
1959+
* Provides query predicates for testing adjacent SSA references and
1960+
* insertion of phi reads.
1961+
*/
1962+
module TestAdjacentRefs {
1963+
private newtype TRef =
1964+
TRefRead(BasicBlock bb, int i, SourceVariable v) { variableRead(bb, i, v, true) } or
1965+
TRefDef(Definition def) or
1966+
TRefPhiRead(BasicBlock bb, SourceVariable v) { synthPhiRead(bb, v) }
1967+
1968+
/**
1969+
* An SSA reference. This is either a certain read, a definition, or a
1970+
* synthesized phi read.
1971+
*/
1972+
class Ref extends TRef {
1973+
/** Gets the source variable referenced by this reference. */
1974+
SourceVariable getSourceVariable() {
1975+
this = TRefRead(_, _, result)
1976+
or
1977+
exists(Definition def | this = TRefDef(def) and def.getSourceVariable() = result)
1978+
or
1979+
this = TRefPhiRead(_, result)
1980+
}
1981+
1982+
predicate isPhiRead() { this = TRefPhiRead(_, _) }
1983+
1984+
/** Gets a textual representation of this SSA reference. */
1985+
string toString() {
1986+
this = TRefRead(_, _, _) and result = "SSA read(" + this.getSourceVariable() + ")"
1987+
or
1988+
exists(Definition def | this = TRefDef(def) and result = def.toString())
1989+
or
1990+
this = TRefPhiRead(_, _) and result = "SSA phi read(" + this.getSourceVariable() + ")"
1991+
}
1992+
1993+
/** Gets the location of this SSA reference. */
1994+
Location getLocation() {
1995+
exists(BasicBlock bb, int i |
1996+
this = TRefRead(bb, i, _) and bb.getNode(i).getLocation() = result
1997+
)
1998+
or
1999+
exists(Definition def | this = TRefDef(def) and def.getLocation() = result)
2000+
or
2001+
exists(BasicBlock bb | this = TRefPhiRead(bb, _) and bb.getLocation() = result)
2002+
}
2003+
2004+
/** Holds if this reference of `v` occurs in `bb` at index `i`. */
2005+
predicate accessAt(BasicBlock bb, int i, SourceVariable v) {
2006+
this = TRefRead(bb, i, v)
2007+
or
2008+
exists(Definition def | this = TRefDef(def) and def.definesAt(v, bb, i))
2009+
or
2010+
this = TRefPhiRead(bb, v) and i = -1
2011+
}
2012+
}
2013+
2014+
/**
2015+
* Holds if `r2` is a certain read or uncertain write, and `r1` is the
2016+
* unique prior reference.
2017+
*/
2018+
query predicate adjacentRefRead(Ref r1, Ref r2) {
2019+
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2, SourceVariable v |
2020+
r1.accessAt(bb1, i1, v) and
2021+
r2.accessAt(bb2, i2, v) and
2022+
AdjacentSsaRefs::adjacentRefRead(bb1, i1, bb2, i2, v)
2023+
)
2024+
}
2025+
2026+
/**
2027+
* Holds if `phi` is a phi definition or phi read and `input` is one its
2028+
* inputs without any other reference in-between.
2029+
*/
2030+
query predicate adjacentRefPhi(Ref input, Ref phi) {
2031+
exists(BasicBlock bb, int i, BasicBlock bbPhi, SourceVariable v |
2032+
input.accessAt(bb, i, v) and
2033+
phi.accessAt(bbPhi, -1, v) and
2034+
AdjacentSsaRefs::adjacentRefPhi(bb, i, _, bbPhi, v)
2035+
)
2036+
}
2037+
}
19572038
}

0 commit comments

Comments
 (0)