mirror of
https://github.com/github/codeql.git
synced 2025-12-18 01:33:15 +01:00
A number of CPP library tests contain `// query-type: graph` annotations that make the test driver compare the output from the test query in a special mode. (This feature is not used by other languages). It's somewhat awkward in the implementation of `codeql test run` that this annotation is not an ordinary item of query metadata -- essentially it means that _every_ test query has to be opened and read an extra time to look for this annotation. I'd like to move towards using ordinary query metadata for this, since the QL compiler already parses it anyway. For the time being, give the annotation in both old and new syntaxes, until a CLI that recognizes both has been released.
78 lines
2.2 KiB
Plaintext
78 lines
2.2 KiB
Plaintext
/**
|
|
* query-type: graph
|
|
*
|
|
* @kind graph-equivalence-test
|
|
*/
|
|
|
|
import cpp
|
|
import semmle.code.cpp.pointsto.PointsTo
|
|
|
|
newtype TElementOrSet =
|
|
MkElement(Element e) or
|
|
MkSet(int i) { pointstosets(i, _) }
|
|
|
|
class ElementOrSet extends TElementOrSet {
|
|
int asSet() { this = MkSet(result) }
|
|
|
|
Element asElement() { this = MkElement(result) }
|
|
|
|
string toString() {
|
|
result = any(Element e | this = MkElement(e)).toString() or
|
|
result = any(int set | this = MkSet(set)).toString()
|
|
}
|
|
}
|
|
|
|
predicate isSetFlowEnd(boolean isEdge, int x, int y, string label) {
|
|
(setflow(x, _) or setflow(_, x)) and
|
|
isEdge = false and
|
|
x = y and
|
|
label =
|
|
"set: {" + concat(Element e | pointstosets(x, unresolveElement(e)) | e.toString(), ", ") + "}"
|
|
}
|
|
|
|
predicate isSetFlow(boolean isEdge, int x, int y, string label) {
|
|
isEdge = true and
|
|
setflow(x, y) and
|
|
label = "sf"
|
|
}
|
|
|
|
predicate isPointsToSetSrc(boolean isEdge, int x, int y, string label) {
|
|
pointstosets(x, _) and
|
|
isEdge = false and
|
|
x = y and
|
|
label =
|
|
"set: {" + concat(Element e | pointstosets(x, unresolveElement(e)) | e.toString(), ", ") + "}"
|
|
}
|
|
|
|
predicate isPointsToSetDest(boolean isEdge, Element x, Element y, string label) {
|
|
exists(string loc, string name |
|
|
pointstosets(_, unresolveElement(x)) and
|
|
isEdge = false and
|
|
x = y and
|
|
(
|
|
if exists(x.getLocation().toString())
|
|
then loc = x.getLocation().toString()
|
|
else loc = "<no location>"
|
|
) and
|
|
(if exists(x.toString()) then name = x.toString() else name = "<no toString>") and
|
|
label = loc + "\n" + name
|
|
)
|
|
}
|
|
|
|
predicate isPointsToSets(boolean isEdge, int x, Element y, string label) {
|
|
isEdge = true and
|
|
pointstosets(x, unresolveElement(y)) and
|
|
label =
|
|
"pt: {" + concat(Element e | pointstosets(x, unresolveElement(e)) | e.toString(), ", ") +
|
|
"} -> " + y.toString()
|
|
}
|
|
|
|
from boolean isEdge, ElementOrSet x, ElementOrSet y, string label
|
|
where
|
|
isSetFlowEnd(isEdge, x.asSet(), y.asSet(), label) or
|
|
isSetFlow(isEdge, x.asSet(), y.asSet(), label) or
|
|
isPointsToSetSrc(isEdge, x.asSet(), y.asSet(), label) or
|
|
isPointsToSetDest(isEdge, x.asElement(), y.asElement(), label) or
|
|
isPointsToSets(isEdge, x.asSet(), y.asElement(), label)
|
|
select "pointsto", isEdge, x, y, label
|