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:7:98:8 | ! ... | unnecessary NULL check before call to $@ | test.cpp:101:3:101:6 | call to free | free |
8
+ | test.cpp:98:8:98:8 | x | unnecessary NULL check before call to $@ | test.cpp:101:3:101:6 | call to free | free |
9
+ | test.cpp:106:7:106:18 | ... != ... | unnecessary NULL check before call to $@ | test.cpp:107:5:107:8 | call to free | free |
10
+ | test.cpp:113:7:113:18 | ... != ... | 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 in the first operand of the comma operator
114
+ inspect (x), free (x);
115
+ }
You can’t perform that action at this time.
0 commit comments