Skip to content

Commit 4e18cca

Browse files
committed
C++: Add a way to test the behavior of 'asExpr' and 'toString' on dataflow nodes.
1 parent 6724227 commit 4e18cca

File tree

5 files changed

+104
-0
lines changed

5 files changed

+104
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
testFailures
2+
failures
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import cpp
2+
import TestUtilities.InlineExpectationsTest
3+
import semmle.code.cpp.dataflow.new.DataFlow::DataFlow
4+
5+
bindingset[s]
6+
string quote(string s) { if s.matches("% %") then result = "\"" + s + "\"" else result = s }
7+
8+
string formatNumberOfNodesForIndirectExpr(Expr e) {
9+
exists(int n | n = strictcount(Node node | node.asIndirectExpr() = e) |
10+
n > 1 and result = ": " + n
11+
)
12+
}
13+
14+
module AsIndirectExprTest implements TestSig {
15+
string getARelevantTag() { result = ["asIndirectExpr", "numberOfIndirectNodes"] }
16+
17+
predicate hasActualResult(Location location, string element, string tag, string value) {
18+
exists(Node n, Expr e, string exprString |
19+
e = n.asIndirectExpr() and
20+
location = e.getLocation() and
21+
element = n.toString() and
22+
exprString = e.toString()
23+
|
24+
tag = "asIndirectExpr" and
25+
(
26+
// The toString on an indirect is often formatted like `***myExpr`.
27+
// If the node's `toString` is of that form then we don't show it in
28+
// the expected output.
29+
if element.matches("%" + exprString)
30+
then value = quote(exprString)
31+
else value = quote(exprString + "(" + element + ")")
32+
)
33+
or
34+
tag = "numberOfIndirectNodes" and
35+
value = quote(exprString + formatNumberOfNodesForIndirectExpr(e))
36+
)
37+
}
38+
}
39+
40+
import MakeTest<AsIndirectExprTest>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
void take_const_ref_int(const int &);
2+
3+
void test_materialize_temp_int()
4+
{
5+
take_const_ref_int(42); // $ asExpr=42 numberOfNodes="42: 2" asIndirectExpr=42 numberOfIndirectNodes="42: 2"
6+
}
7+
8+
struct A {};
9+
10+
A get();
11+
void take_const_ref(const A &);
12+
13+
void test1(){
14+
take_const_ref(get()); // $ asExpr="call to get" numberOfNodes="call to get: 2" asIndirectExpr="call to get" numberOfIndirectNodes="call to get: 2"
15+
}
16+
17+
void take_ref(A &);
18+
19+
A& get_ref();
20+
21+
void test2() {
22+
take_ref(get_ref()); // $ asExpr="call to get_ref" asIndirectExpr="call to get_ref"
23+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
testFailures
2+
failures
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import cpp
2+
import TestUtilities.InlineExpectationsTest
3+
import semmle.code.cpp.dataflow.new.DataFlow::DataFlow
4+
5+
bindingset[s]
6+
string quote(string s) { if s.matches("% %") then result = "\"" + s + "\"" else result = s }
7+
8+
string formatNumberOfNodesForExpr(Expr e) {
9+
exists(int n | n = strictcount(Node node | node.asExpr() = e) | n > 1 and result = ": " + n)
10+
}
11+
12+
module AsExprTest implements TestSig {
13+
string getARelevantTag() { result = ["asExpr", "numberOfNodes"] }
14+
15+
predicate hasActualResult(Location location, string element, string tag, string value) {
16+
exists(Node n, Expr e, string exprString |
17+
e = n.asExpr() and
18+
location = e.getLocation() and
19+
element = n.toString() and
20+
exprString = e.toString()
21+
|
22+
tag = "asExpr" and
23+
(
24+
// If the `toString` on the node is identical to the `toString` of the
25+
// expression then we don't show it in the expected output.
26+
if exprString = element
27+
then value = quote(exprString)
28+
else value = quote(exprString + "(" + element + ")")
29+
)
30+
or
31+
tag = "numberOfNodes" and
32+
value = quote(exprString + formatNumberOfNodesForExpr(e))
33+
)
34+
}
35+
}
36+
37+
import MakeTest<AsExprTest>

0 commit comments

Comments
 (0)