Skip to content

Commit c4cca83

Browse files
authored
Merge pull request github#5196 from MathiasVP/fix-dataflow-regression-const-member-function
C++: Fix missing dataflow "out of" const member functions
2 parents f81860c + 3082d70 commit c4cca83

File tree

6 files changed

+196
-6
lines changed

6 files changed

+196
-6
lines changed

cpp/ql/src/semmle/code/cpp/dataflow/internal/AddressFlow.qll

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,22 @@ private predicate lvalueToUpdate(Expr lvalue, Expr outer, ControlFlowNode node)
131131
exists(Call call | node = call |
132132
outer = call.getQualifier().getFullyConverted() and
133133
outer.getUnspecifiedType() instanceof Class and
134-
not call.getTarget().hasSpecifier("const")
134+
not (
135+
call.getTarget().hasSpecifier("const") and
136+
// Given the following program:
137+
// ```
138+
// struct C {
139+
// void* data_;
140+
// void* data() const { return data; }
141+
// };
142+
// C c;
143+
// memcpy(c.data(), source, 16)
144+
// ```
145+
// the data pointed to by `c.data_` is potentially modified by the call to `memcpy` even though
146+
// `C::data` has a const specifier. So we further place the restriction that the type returned
147+
// by `call` should not be of the form `const T*` (for some deeply const type `T`).
148+
call.getType().isDeeplyConstBelow()
149+
)
135150
)
136151
or
137152
assignmentTo(outer, node)
@@ -170,7 +185,11 @@ private predicate pointerToUpdate(Expr pointer, Expr outer, ControlFlowNode node
170185
or
171186
outer = call.getQualifier().getFullyConverted() and
172187
outer.getUnspecifiedType() instanceof PointerType and
173-
not call.getTarget().hasSpecifier("const")
188+
not (
189+
call.getTarget().hasSpecifier("const") and
190+
// See the `lvalueToUpdate` case for an explanation of this conjunct.
191+
call.getType().isDeeplyConstBelow()
192+
)
174193
)
175194
or
176195
exists(PointerFieldAccess fa |

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@ argHasPostUpdate
3636
| arrays.cpp:10:8:10:15 | * ... | ArgumentNode is missing PostUpdateNode. |
3737
| arrays.cpp:16:8:16:13 | access to array | ArgumentNode is missing PostUpdateNode. |
3838
| arrays.cpp:17:8:17:13 | access to array | ArgumentNode is missing PostUpdateNode. |
39-
| by_reference.cpp:51:8:51:8 | s | ArgumentNode is missing PostUpdateNode. |
40-
| by_reference.cpp:57:8:57:8 | s | ArgumentNode is missing PostUpdateNode. |
41-
| by_reference.cpp:63:8:63:8 | s | ArgumentNode is missing PostUpdateNode. |
4239
postWithInFlow
4340
| A.cpp:25:13:25:13 | c [post update] | PostUpdateNode should not be the target of local flow. |
4441
| A.cpp:27:28:27:28 | c [post update] | PostUpdateNode should not be the target of local flow. |

cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,18 @@
227227
| by_reference.cpp:20:23:20:27 | value | AST only |
228228
| by_reference.cpp:24:19:24:22 | this | AST only |
229229
| by_reference.cpp:24:25:24:29 | value | AST only |
230+
| by_reference.cpp:40:12:40:15 | this | AST only |
230231
| by_reference.cpp:50:3:50:3 | s | AST only |
231232
| by_reference.cpp:50:17:50:26 | call to user_input | AST only |
233+
| by_reference.cpp:51:8:51:8 | s | AST only |
232234
| by_reference.cpp:51:10:51:20 | call to getDirectly | AST only |
233235
| by_reference.cpp:56:3:56:3 | s | AST only |
234236
| by_reference.cpp:56:19:56:28 | call to user_input | AST only |
237+
| by_reference.cpp:57:8:57:8 | s | AST only |
235238
| by_reference.cpp:57:10:57:22 | call to getIndirectly | AST only |
236239
| by_reference.cpp:62:3:62:3 | s | AST only |
237240
| by_reference.cpp:62:25:62:34 | call to user_input | AST only |
241+
| by_reference.cpp:63:8:63:8 | s | AST only |
238242
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember | AST only |
239243
| by_reference.cpp:68:17:68:18 | & ... | AST only |
240244
| by_reference.cpp:68:21:68:30 | call to user_input | AST only |

cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,14 +266,18 @@
266266
| by_reference.cpp:20:23:20:27 | value |
267267
| by_reference.cpp:24:19:24:22 | this |
268268
| by_reference.cpp:24:25:24:29 | value |
269+
| by_reference.cpp:40:12:40:15 | this |
269270
| by_reference.cpp:50:3:50:3 | s |
270271
| by_reference.cpp:50:17:50:26 | call to user_input |
272+
| by_reference.cpp:51:8:51:8 | s |
271273
| by_reference.cpp:51:10:51:20 | call to getDirectly |
272274
| by_reference.cpp:56:3:56:3 | s |
273275
| by_reference.cpp:56:19:56:28 | call to user_input |
276+
| by_reference.cpp:57:8:57:8 | s |
274277
| by_reference.cpp:57:10:57:22 | call to getIndirectly |
275278
| by_reference.cpp:62:3:62:3 | s |
276279
| by_reference.cpp:62:25:62:34 | call to user_input |
280+
| by_reference.cpp:63:8:63:8 | s |
277281
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
278282
| by_reference.cpp:68:17:68:18 | & ... |
279283
| by_reference.cpp:68:21:68:30 | call to user_input |

0 commit comments

Comments
 (0)