Skip to content

Commit 7f13d4c

Browse files
committed
C++: Improve EscapesTree analysis in the presence of temporary objects.
1 parent 8d024c7 commit 7f13d4c

File tree

7 files changed

+15
-7
lines changed

7 files changed

+15
-7
lines changed

cpp/ql/src/semmle/code/cpp/dataflow/EscapesTree.qll

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,14 @@ private predicate addressMayEscapeMutablyAt(Expr e) {
222222
// If the address has been cast to an integral type, conservatively assume that it may eventually be cast back to a
223223
// pointer to non-const type.
224224
t instanceof IntegralType
225+
or
226+
// If we go through a temporary object step, we can take a reference to a temporary const pointer
227+
// object, where the pointer doesn't point to a const value
228+
exists(TemporaryObjectExpr temp, PointerType pt |
229+
temp.getConversion() = e and pt = temp.getType().stripTopLevelSpecifiers()
230+
|
231+
not pt.getBaseType().isConst()
232+
)
225233
)
226234
}
227235

@@ -249,7 +257,7 @@ private predicate addressFromVariableAccess(VariableAccess va, Expr e) {
249257
// `e` could be a pointer that is converted to a reference as the final step,
250258
// meaning that we pass a value that is two dereferences away from referring
251259
// to `va`. This happens, for example, with `void std::vector::push_back(T&&
252-
// value);` when called as `v.push_back(&x)`, for a static variable `x`. It
260+
// value);` when called as `v.push_back(&x)`, for a variable `x`. It
253261
// can also happen when taking a reference to a const pointer to a
254262
// (potentially non-const) value.
255263
exists(Expr pointerValue |

cpp/ql/test/library-tests/defuse/definition.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
| addressOf.cpp:23:9:23:9 | i | addressOf.cpp:24:22:24:30 | call to move |
22
| addressOf.cpp:23:9:23:9 | i | addressOf.cpp:25:25:25:26 | & ... |
3+
| addressOf.cpp:23:9:23:9 | i | addressOf.cpp:26:31:26:32 | & ... |
34
| addressOf.cpp:31:23:31:23 | i | addressOf.cpp:32:18:32:19 | & ... |
45
| addressOf.cpp:31:23:31:23 | i | addressOf.cpp:34:18:34:33 | ... ? ... : ... |
56
| addressOf.cpp:31:23:31:23 | i | addressOf.cpp:35:18:35:23 | & ... |
@@ -78,6 +79,7 @@
7879
| pass_by_ref.cpp:46:7:46:7 | i | pass_by_ref.cpp:49:5:49:7 | ... ++ |
7980
| pass_by_ref.cpp:46:7:46:7 | i | pass_by_ref.cpp:53:22:53:22 | i |
8081
| pass_by_ref.cpp:60:7:60:7 | x | pass_by_ref.cpp:60:10:60:11 | 2 |
82+
| pass_by_ref.cpp:60:7:60:7 | x | pass_by_ref.cpp:61:34:61:35 | & ... |
8183
| pass_by_ref.cpp:66:8:66:8 | p | pass_by_ref.cpp:66:12:66:18 | 0 |
8284
| test.cpp:4:7:4:7 | a | test.cpp:5:3:5:8 | ... = ... |
8385
| test.cpp:4:7:4:7 | a | test.cpp:13:3:13:7 | ... = ... |

cpp/ql/test/library-tests/defuse/definitionUsePair.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
| pass_by_ref.cpp:46:7:46:7 | i | pass_by_ref.cpp:49:5:49:7 | ... ++ | pass_by_ref.cpp:53:22:53:22 | i |
7777
| pass_by_ref.cpp:46:7:46:7 | i | pass_by_ref.cpp:53:22:53:22 | i | pass_by_ref.cpp:54:10:54:10 | i |
7878
| pass_by_ref.cpp:60:7:60:7 | x | pass_by_ref.cpp:60:10:60:11 | 2 | pass_by_ref.cpp:61:35:61:35 | x |
79-
| pass_by_ref.cpp:60:7:60:7 | x | pass_by_ref.cpp:60:10:60:11 | 2 | pass_by_ref.cpp:62:10:62:10 | x |
79+
| pass_by_ref.cpp:60:7:60:7 | x | pass_by_ref.cpp:61:34:61:35 | & ... | pass_by_ref.cpp:62:10:62:10 | x |
8080
| pass_by_ref.cpp:66:8:66:8 | p | pass_by_ref.cpp:66:12:66:18 | 0 | pass_by_ref.cpp:67:34:67:34 | p |
8181
| pass_by_ref.cpp:66:8:66:8 | p | pass_by_ref.cpp:66:12:66:18 | 0 | pass_by_ref.cpp:68:10:68:10 | p |
8282
| test.cpp:4:7:4:7 | a | test.cpp:5:3:5:8 | ... = ... | test.cpp:9:7:9:7 | a |

cpp/ql/test/library-tests/defuse/isAddressOfAccess.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
| addressOf.cpp:14:28:14:29 | d_ | non-const address |
22
| addressOf.cpp:24:32:24:32 | i | non-const address |
33
| addressOf.cpp:25:26:25:26 | i | non-const address |
4-
| addressOf.cpp:26:32:26:32 | i | const address |
4+
| addressOf.cpp:26:32:26:32 | i | non-const address |
55
| addressOf.cpp:32:19:32:19 | i | non-const address |
66
| addressOf.cpp:34:18:34:18 | i | |
77
| addressOf.cpp:34:23:34:23 | i | non-const address |
@@ -151,7 +151,7 @@
151151
| pass_by_ref.cpp:49:5:49:5 | i | |
152152
| pass_by_ref.cpp:53:22:53:22 | i | non-const address |
153153
| pass_by_ref.cpp:54:10:54:10 | i | |
154-
| pass_by_ref.cpp:61:35:61:35 | x | const address |
154+
| pass_by_ref.cpp:61:35:61:35 | x | non-const address |
155155
| pass_by_ref.cpp:62:10:62:10 | x | |
156156
| pass_by_ref.cpp:67:34:67:34 | p | const address |
157157
| pass_by_ref.cpp:68:10:68:10 | p | |

cpp/ql/test/library-tests/defuse/useUsePair.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
| pass_by_ref.cpp:21:7:21:8 | i2 | pass_by_ref.cpp:24:26:24:27 | i2 | pass_by_ref.cpp:27:39:27:40 | i2 |
2626
| pass_by_ref.cpp:21:7:21:8 | i2 | pass_by_ref.cpp:25:27:25:28 | i2 | pass_by_ref.cpp:27:39:27:40 | i2 |
2727
| pass_by_ref.cpp:45:17:45:17 | n | pass_by_ref.cpp:46:11:46:11 | n | pass_by_ref.cpp:48:7:48:7 | n |
28-
| pass_by_ref.cpp:60:7:60:7 | x | pass_by_ref.cpp:61:35:61:35 | x | pass_by_ref.cpp:62:10:62:10 | x |
2928
| pass_by_ref.cpp:66:8:66:8 | p | pass_by_ref.cpp:67:34:67:34 | p | pass_by_ref.cpp:68:10:68:10 | p |
3029
| test.cpp:4:7:4:7 | a | test.cpp:14:7:14:7 | a | test.cpp:18:7:18:7 | a |
3130
| test.cpp:4:7:4:7 | a | test.cpp:14:7:14:7 | a | test.cpp:24:7:24:7 | a |

cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,4 @@
5050
| PointlessComparison.cpp:43:6:43:29 | ... >= ... | Comparison is always true because ... >> ... >= 140737488355327.5. |
5151
| PointlessComparison.cpp:44:6:44:28 | ... >= ... | Comparison is always true because ... >> ... >= 140737488355327.5. |
5252
| RegressionTests.cpp:57:7:57:22 | ... <= ... | Comparison is always true because * ... <= 4294967295. |
53-
| RegressionTests.cpp:125:7:125:11 | ... > ... | Comparison is always false because x <= 0. |
5453
| Templates.cpp:9:10:9:24 | ... <= ... | Comparison is always true because local <= 32767. |

cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/RegressionTests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,5 +122,5 @@ void f(int *const &ref_to_ptr);
122122
void testTempObject() {
123123
int x = 0;
124124
f(&x);
125-
if (x > 0) {} // BAD [FALSE POSITIVE]
125+
if (x > 0) {} // GOOD [NO LONGER REPORTED]
126126
}

0 commit comments

Comments
 (0)