Files
codeql/cpp/ql/test/library-tests/pointsto/basic/sets.ql
Henning Makholm 3d8d340f2a Supplement 'query-type: graph' with actual query metadata
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.
2024-10-22 20:38:00 +02:00

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