Skip to content

Commit

Permalink
Merge pull request #15427 from MathiasVP/asexpr-and-asindirectexpr-tests
Browse files Browse the repository at this point in the history
C++: Add `asExpr` and `asIndirectExpr` library tests (and fix more duplication)
  • Loading branch information
MathiasVP authored Jan 25, 2024
2 parents 2db76c7 + 7916616 commit 863e6c8
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -1484,12 +1484,17 @@ private module IndirectNodeToIndirectExpr<IndirectNodeToIndirectExprSig Sig> {
indirectNodeHasIndirectExpr(node, e, n, indirectionIndex) and
not exists(Expr conv, int adjustedIndirectionIndex |
adjustForReference(e, indirectionIndex, conv, adjustedIndirectionIndex) and
indirectNodeHasIndirectExpr(_, conv, n + 1, adjustedIndirectionIndex)
indirectExprNodeShouldBe(conv, n + 1, adjustedIndirectionIndex)
)
)
}
}

private predicate indirectExprNodeShouldBe(Expr e, int n, int indirectionIndex) {
indirectExprNodeShouldBeIndirectOperand(_, e, n, indirectionIndex) or
indirectExprNodeShouldBeIndirectInstruction(_, e, n, indirectionIndex)
}

private module IndirectOperandIndirectExprNodeImpl implements IndirectNodeToIndirectExprSig {
class IndirectNode = IndirectOperand;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
testFailures
failures
40 changes: 40 additions & 0 deletions cpp/ql/test/library-tests/dataflow/asExpr/test-indirect.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import cpp
import TestUtilities.InlineExpectationsTest
import semmle.code.cpp.dataflow.new.DataFlow::DataFlow

bindingset[s]
string quote(string s) { if s.matches("% %") then result = "\"" + s + "\"" else result = s }

string formatNumberOfNodesForIndirectExpr(Expr e) {
exists(int n | n = strictcount(Node node | node.asIndirectExpr() = e) |
n > 1 and result = ": " + n
)
}

module AsIndirectExprTest implements TestSig {
string getARelevantTag() { result = ["asIndirectExpr", "numberOfIndirectNodes"] }

predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Node n, Expr e, string exprString |
e = n.asIndirectExpr() and
location = e.getLocation() and
element = n.toString() and
exprString = e.toString()
|
tag = "asIndirectExpr" and
(
// The toString on an indirect is often formatted like `***myExpr`.
// If the node's `toString` is of that form then we don't show it in
// the expected output.
if element.matches("%" + exprString)
then value = quote(exprString)
else value = quote(exprString + "(" + element + ")")
)
or
tag = "numberOfIndirectNodes" and
value = quote(exprString + formatNumberOfNodesForIndirectExpr(e))
)
}
}

import MakeTest<AsIndirectExprTest>
23 changes: 23 additions & 0 deletions cpp/ql/test/library-tests/dataflow/asExpr/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
void take_const_ref_int(const int &);

void test_materialize_temp_int()
{
take_const_ref_int(42); // $ asExpr=42 numberOfNodes="42: 2" asIndirectExpr=42
}

struct A {};

A get();
void take_const_ref(const A &);

void test1(){
take_const_ref(get()); // $ asExpr="call to get" numberOfNodes="call to get: 2" asIndirectExpr="call to get"
}

void take_ref(A &);

A& get_ref();

void test2() {
take_ref(get_ref()); // $ asExpr="call to get_ref" asIndirectExpr="call to get_ref"
}
2 changes: 2 additions & 0 deletions cpp/ql/test/library-tests/dataflow/asExpr/test.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
testFailures
failures
37 changes: 37 additions & 0 deletions cpp/ql/test/library-tests/dataflow/asExpr/test.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import cpp
import TestUtilities.InlineExpectationsTest
import semmle.code.cpp.dataflow.new.DataFlow::DataFlow

bindingset[s]
string quote(string s) { if s.matches("% %") then result = "\"" + s + "\"" else result = s }

string formatNumberOfNodesForExpr(Expr e) {
exists(int n | n = strictcount(Node node | node.asExpr() = e) | n > 1 and result = ": " + n)
}

module AsExprTest implements TestSig {
string getARelevantTag() { result = ["asExpr", "numberOfNodes"] }

predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Node n, Expr e, string exprString |
e = n.asExpr() and
location = e.getLocation() and
element = n.toString() and
exprString = e.toString()
|
tag = "asExpr" and
(
// If the `toString` on the node is identical to the `toString` of the
// expression then we don't show it in the expected output.
if exprString = element
then value = quote(exprString)
else value = quote(exprString + "(" + element + ")")
)
or
tag = "numberOfNodes" and
value = quote(exprString + formatNumberOfNodesForExpr(e))
)
}
}

import MakeTest<AsExprTest>

0 comments on commit 863e6c8

Please sign in to comment.