Skip to content

Commit 08b63d4

Browse files
committed
C++: Test to show lack of flow from this by ref.
The `test_nonMemberSetA` also shows how the lack of flow through `&` is a problem for non-member getters, but that's addressed on a separate branch.
1 parent ef96288 commit 08b63d4

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
void sink(void *o);
2+
void *user_input(void);
3+
4+
struct S {
5+
void *a;
6+
7+
/*
8+
* Setters
9+
*/
10+
11+
friend void nonMemberSetA(struct S *s, void *value) {
12+
s->a = value;
13+
}
14+
15+
void setDirectly(void *value) {
16+
this->a = value;
17+
}
18+
19+
void setIndirectly(void *value) {
20+
this->setDirectly(value);
21+
}
22+
23+
void setThroughNonMember(void *value) {
24+
nonMemberSetA(this, value);
25+
}
26+
27+
/*
28+
* Getters
29+
*/
30+
31+
friend void *nonMemberGetA(const struct S *s) {
32+
return s->a;
33+
}
34+
35+
void* getDirectly() const {
36+
return this->a;
37+
}
38+
39+
void* getIndirectly() const {
40+
return this->getDirectly();
41+
}
42+
43+
void *getThroughNonMember() const {
44+
return nonMemberGetA(this);
45+
}
46+
};
47+
48+
void test_setDirectly() {
49+
S s;
50+
s.setDirectly(user_input());
51+
sink(s.getDirectly()); // flow
52+
}
53+
54+
void test_setIndirectly() {
55+
S s;
56+
s.setIndirectly(user_input());
57+
sink(s.getIndirectly()); // flow
58+
}
59+
60+
void test_setThroughNonMember() {
61+
S s;
62+
s.setThroughNonMember(user_input());
63+
sink(s.getThroughNonMember()); // flow [NOT DETECTED]
64+
}
65+
66+
void test_nonMemberSetA() {
67+
S s;
68+
nonMemberSetA(&s, user_input());
69+
sink(nonMemberGetA(&s)); // flow [NOT DETECTED due to lack of flow through &]
70+
}

cpp/ql/test/library-tests/dataflow/fields/flow.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@ edges
109109
| aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:92:3:92:23 | ... = ... |
110110
| aliasing.cpp:93:8:93:8 | w [s, m1] | aliasing.cpp:93:10:93:10 | s [m1] |
111111
| aliasing.cpp:93:10:93:10 | s [m1] | aliasing.cpp:93:12:93:13 | m1 |
112+
| by_reference.cpp:50:3:50:3 | s [post update] [a] | by_reference.cpp:51:8:51:8 | s [a] |
113+
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:3:50:3 | s [post update] [a] |
114+
| by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:51:10:51:20 | call to getDirectly |
115+
| by_reference.cpp:56:3:56:3 | s [post update] [a] | by_reference.cpp:57:8:57:8 | s [a] |
116+
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:56:3:56:3 | s [post update] [a] |
117+
| by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:57:10:57:22 | call to getIndirectly |
112118
| complex.cpp:34:15:34:15 | b [f, a_] | complex.cpp:44:8:44:8 | b [f, a_] |
113119
| complex.cpp:34:15:34:15 | b [f, b_] | complex.cpp:45:8:45:8 | b [f, b_] |
114120
| complex.cpp:44:8:44:8 | b [f, a_] | complex.cpp:44:10:44:10 | f [a_] |
@@ -195,6 +201,8 @@ edges
195201
| aliasing.cpp:30:11:30:12 | m1 | aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:30:11:30:12 | m1 | m1 flows from $@ | aliasing.cpp:13:10:13:19 | call to user_input | call to user_input |
196202
| aliasing.cpp:62:14:62:15 | m1 | aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:62:14:62:15 | m1 | m1 flows from $@ | aliasing.cpp:60:11:60:20 | call to user_input | call to user_input |
197203
| aliasing.cpp:93:12:93:13 | m1 | aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:93:12:93:13 | m1 | m1 flows from $@ | aliasing.cpp:92:12:92:21 | call to user_input | call to user_input |
204+
| by_reference.cpp:51:10:51:20 | call to getDirectly | by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:51:10:51:20 | call to getDirectly | call to getDirectly flows from $@ | by_reference.cpp:50:17:50:26 | call to user_input | call to user_input |
205+
| by_reference.cpp:57:10:57:22 | call to getIndirectly | by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:57:10:57:22 | call to getIndirectly | call to getIndirectly flows from $@ | by_reference.cpp:56:19:56:28 | call to user_input | call to user_input |
198206
| complex.cpp:44:12:44:12 | call to a | complex.cpp:55:13:55:22 | call to user_input | complex.cpp:44:12:44:12 | call to a | call to a flows from $@ | complex.cpp:55:13:55:22 | call to user_input | call to user_input |
199207
| complex.cpp:44:12:44:12 | call to a | complex.cpp:57:13:57:22 | call to user_input | complex.cpp:44:12:44:12 | call to a | call to a flows from $@ | complex.cpp:57:13:57:22 | call to user_input | call to user_input |
200208
| complex.cpp:45:12:45:12 | call to b | complex.cpp:56:13:56:22 | call to user_input | complex.cpp:45:12:45:12 | call to b | call to b flows from $@ | complex.cpp:56:13:56:22 | call to user_input | call to user_input |

0 commit comments

Comments
 (0)