Skip to content

Commit 176acab

Browse files
committed
C++: Ignore free calls that are macro defined or #if/#ifdef guarded
1 parent a31e983 commit 176acab

File tree

3 files changed

+16
-7
lines changed

3 files changed

+16
-7
lines changed

cpp/ql/src/experimental/Best Practices/GuardedFree.ql

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@ class FreeCall extends FunctionCall {
1818
FreeCall() { this.getTarget().hasGlobalName("free") }
1919
}
2020

21+
predicate isAffectedByMacro(FreeCall fc, BasicBlock bb) {
22+
fc.isInMacroExpansion()
23+
or
24+
exists(PreprocessorBranch ppb, Location bbLoc, Location ppbLoc |
25+
bbLoc = bb.(Stmt).getLocation() and ppbLoc = ppb.getLocation()
26+
|
27+
bbLoc.getStartLine() < ppbLoc.getStartLine() and
28+
ppbLoc.getEndLine() < bbLoc.getEndLine()
29+
)
30+
}
31+
2132
from GuardCondition gc, FreeCall fc, Variable v, BasicBlock bb
2233
where
2334
gc.ensuresEq(v.getAnAccess(), 0, bb, false) and
@@ -28,5 +39,6 @@ where
2839
or
2940
strictcount(bb.(BlockStmt).getAStmt()) = 1
3041
) and
31-
strictcount(BasicBlock bb2 | gc.ensuresEq(_, 0, bb2, _) | bb2) = 1
42+
strictcount(BasicBlock bb2 | gc.ensuresEq(_, 0, bb2, _) | bb2) = 1 and
43+
not isAffectedByMacro(fc, bb)
3244
select gc, "unnecessary NULL check before call to $@", fc, "free"

cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/GuardedFree.expected

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,5 @@
33
| test.cpp:31:7:31:24 | ... \|\| ... | unnecessary NULL check before call to $@ | test.cpp:35:3:35:6 | call to free | free |
44
| test.cpp:42:7:42:7 | x | unnecessary NULL check before call to $@ | test.cpp:43:5:43:8 | call to free | free |
55
| test.cpp:49:7:49:7 | x | unnecessary NULL check before call to $@ | test.cpp:50:5:50:8 | call to free | free |
6-
| test.cpp:75:7:75:7 | x | unnecessary NULL check before call to $@ | test.cpp:76:5:76:14 | call to free | free |
7-
| test.cpp:81:7:81:7 | x | unnecessary NULL check before call to $@ | test.cpp:85:5:85:8 | call to free | free |
8-
| test.cpp:94:12:94:12 | x | unnecessary NULL check before call to $@ | test.cpp:94:3:94:13 | call to free | free |
96
| test.cpp:106:7:106:18 | ... != ... | unnecessary NULL check before call to $@ | test.cpp:107:5:107:8 | call to free | free |
107
| test.cpp:113:7:113:18 | ... != ... | unnecessary NULL check before call to $@ | test.cpp:114:17:114:20 | call to free | free |

cpp/ql/test/experimental/query-tests/Best Practices/GuardedFree/test.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,13 @@ bool test8(char *x) {
7272
#endif
7373

7474
void test9(char *x) {
75-
if (x) { // GOOD [FALSE POSITIVE]: macro may make free behave unexpectedly when compiled differently
75+
if (x) { // GOOD: macro may make free behave unexpectedly when compiled differently
7676
my_free(x);
7777
}
7878
}
7979

8080
void test10(char *x) {
81-
if (x) { // GOOD [FALSE POSITIVE]: #ifdef may make free behave unexpectedly when compiled differently
81+
if (x) { // GOOD: #ifdef may make free behave unexpectedly when compiled differently
8282
#ifdef FOO
8383
free(x - 1);
8484
#else
@@ -91,7 +91,7 @@ void test10(char *x) {
9191
if (x) free(x);
9292

9393
void test11(char *x) {
94-
TRY_FREE(x) // BAD
94+
TRY_FREE(x) // BAD [NOT DETECTED]
9595
}
9696

9797
bool test12(char *x) {

0 commit comments

Comments
 (0)