Skip to content

Commit a8f2cbc

Browse files
authored
Merge pull request #16331 from mario-campos/mario-campos/guarded-free
Cpp: new experimental query cpp/guarded-free
2 parents 397e641 + 5a7a1dc commit a8f2cbc

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
void test()
2+
{
3+
char *foo = malloc(100);
4+
5+
// BAD
6+
if (foo)
7+
free(foo);
8+
9+
// GOOD
10+
free(foo);
11+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE qhelp SYSTEM "qhelp.dtd">
2+
<qhelp>
3+
<overview>
4+
<p>The <code>free</code> function, which deallocates heap memory, may accept a NULL pointer and take no action. Therefore, it is unnecessary to check its argument for the value of NULL before a function call to <code>free</code>. As such, these guards may hinder performance and readability.</p>
5+
</overview>
6+
<recommendation>
7+
<p>A function call to <code>free</code> should not depend upon the value of its argument. Delete the <code>if</code> condition preceeding a function call to <code>free</code> when its only purpose is to check the value of the pointer to be freed.</p>
8+
</recommendation>
9+
<example>
10+
<sample src = "GuardedFree.cpp" />
11+
</example>
12+
<references>
13+
<li>
14+
The Open Group Base Specifications Issue 7, 2018 Edition:
15+
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html">free - free allocated memory</a>
16+
</li>
17+
</references>
18+
</qhelp>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @name Guarded Free
3+
* @description NULL-condition guards before function calls to the memory-deallocation
4+
* function free(3) are unnecessary, because passing NULL to free(3) is a no-op.
5+
* @kind problem
6+
* @problem.severity recommendation
7+
* @precision very-high
8+
* @id cpp/guarded-free
9+
* @tags maintainability
10+
* readability
11+
* experimental
12+
*/
13+
14+
import cpp
15+
import semmle.code.cpp.controlflow.Guards
16+
17+
class FreeCall extends FunctionCall {
18+
FreeCall() { this.getTarget().hasGlobalName("free") }
19+
}
20+
21+
from GuardCondition gc, FreeCall fc, Variable v, BasicBlock bb
22+
where
23+
gc.ensuresEq(v.getAnAccess(), 0, bb, false) and
24+
fc.getArgument(0) = v.getAnAccess() and
25+
bb = fc.getEnclosingStmt()
26+
select gc, "unnecessary NULL check before call to $@", fc, "free"

0 commit comments

Comments
 (0)