File tree Expand file tree Collapse file tree 3 files changed +126
-0
lines changed
cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree Expand file tree Collapse file tree 3 files changed +126
-0
lines changed Original file line number Diff line number Diff line change 1+ | test.cpp:5:7:5:7 | x | unnecessary NULL check before call to $@ | test.cpp:6:5:6:8 | call to free | free |
2+ | test.cpp:23:7:23:7 | x | unnecessary NULL check before call to $@ | test.cpp:26:5:26:8 | call to free | free |
3+ | test.cpp:31:7:31:8 | ! ... | unnecessary NULL check before call to $@ | test.cpp:35:3:35:6 | call to free | free |
4+ | test.cpp:31:7:31:24 | ... \|\| ... | unnecessary NULL check before call to $@ | test.cpp:35:3:35:6 | call to free | free |
5+ | test.cpp:31:8:31:8 | x | unnecessary NULL check before call to $@ | test.cpp:35:3:35:6 | call to free | free |
6+ | test.cpp:94:12:94:12 | x | unnecessary NULL check before call to $@ | test.cpp:94:3:94:13 | call to free | free |
7+ | test.cpp:98:6:98:7 | ! ... | unnecessary NULL check before call to $@ | test.cpp:101:3:101:6 | call to free | free |
8+ | test.cpp:98:7:98:7 | x | unnecessary NULL check before call to $@ | test.cpp:101:3:101:6 | call to free | free |
9+ | test.cpp:106:6:106:17 | ... != ... | unnecessary NULL check before call to $@ | test.cpp:107:5:107:8 | call to free | free |
10+ | test.cpp:113:6:113:17 | ... != ... | unnecessary NULL check before call to $@ | test.cpp:114:17:114:20 | call to free | free |
Original file line number Diff line number Diff line change 1+ experimental/Best Practices/GuardedFree.ql
Original file line number Diff line number Diff line change 1+ extern " C" void free (void *ptr);
2+ extern " C" int strcmp (const char *s1, const char *s2);
3+
4+ void test0 (int *x) {
5+ if (x) // BAD
6+ free (x);
7+ }
8+
9+ void test1 (int *x) {
10+ if (x) { // BAD
11+ free (x);
12+ }
13+ }
14+
15+ void test2 (int *x) {
16+ if (x) { // GOOD: x is being accessed in the body of the if
17+ *x = 42 ;
18+ free (x);
19+ }
20+ }
21+
22+ void test3 (int *x, bool b) {
23+ if (x) { // GOOD [FALSE POSITIVE]: x is being accessed in the body of the if
24+ if (b)
25+ *x = 42 ;
26+ free (x);
27+ }
28+ }
29+
30+ bool test4 (char *x, char *y) {
31+ if (!x || strcmp (x, y)) { // GOOD [FALSE POSITIVE]: x is being accessed in the guard and return value depends on x
32+ free (x);
33+ return true ;
34+ }
35+ free (x);
36+ return false ;
37+ }
38+
39+ void test5 (char *x) {
40+ if (x)
41+ *x = 42 ;
42+ if (x) { // BAD
43+ free (x);
44+ }
45+ }
46+
47+ void test6 (char *x) {
48+ *x = 42 ;
49+ if (x) { // BAD
50+ free (x);
51+ }
52+ }
53+
54+ void test7 (char *x) {
55+ if (x || x) { // BAD [NOT DETECTED]
56+ free (x);
57+ }
58+ }
59+
60+ bool test8 (char *x) {
61+ if (x) { // GOOD: return value depends on x
62+ free (x);
63+ return true ;
64+ }
65+ return false ;
66+ }
67+
68+ #ifdef FOO
69+ #define my_free (x ) free(x - 1 )
70+ #else
71+ #define my_free (x ) free(x)
72+ #endif
73+
74+ void test9 (char *x) {
75+ if (x) { // GOOD: macro may make free behave unexpectedly when compiled differently
76+ my_free (x);
77+ }
78+ }
79+
80+ void test10 (char *x) {
81+ if (x) { // GOOD: #ifdef may make free behave unexpectedly when compiled differently
82+ #ifdef FOO
83+ free (x - 1 );
84+ #else
85+ free (x);
86+ #endif
87+ }
88+ }
89+
90+ #define TRY_FREE (x ) \
91+ if (x) free(x);
92+
93+ void test11 (char *x) {
94+ TRY_FREE (x) // BAD
95+ }
96+
97+ bool test12 (char *x) {
98+ if (!x) // GOOD [FALSE POSITIVE]: return value depends on x
99+ return false ;
100+
101+ free (x);
102+ return true ;
103+ }
104+
105+ void test13 (char *x) {
106+ if (x != nullptr ) // BAD
107+ free (x);
108+ }
109+
110+ void inspect (char *x);
111+
112+ void test14 (char *x) {
113+ if (x != nullptr ) // GOOD [FALSE POSITIVE]: x might be accessed
114+ inspect (x), free (x);
115+ }
You can’t perform that action at this time.
0 commit comments