@@ -18,9 +18,31 @@ class FreeCall extends FunctionCall {
1818 FreeCall ( ) { this .getTarget ( ) .hasGlobalName ( "free" ) }
1919}
2020
21+ predicate blockContainsPreprocessorBranches ( BasicBlock bb ) {
22+ exists ( PreprocessorBranch ppb , Location bbLoc , Location ppbLoc |
23+ bbLoc = bb .( Stmt ) .getLocation ( ) and ppbLoc = ppb .getLocation ( )
24+ |
25+ bbLoc .getFile ( ) = ppb .getFile ( ) and
26+ bbLoc .getStartLine ( ) < ppbLoc .getStartLine ( ) and
27+ ppbLoc .getEndLine ( ) < bbLoc .getEndLine ( )
28+ )
29+ }
30+
2131from GuardCondition gc , FreeCall fc , Variable v , BasicBlock bb
2232where
2333 gc .ensuresEq ( v .getAnAccess ( ) , 0 , bb , false ) and
2434 fc .getArgument ( 0 ) = v .getAnAccess ( ) and
25- bb = fc .getEnclosingStmt ( )
35+ bb = fc .getBasicBlock ( ) and
36+ (
37+ // No block statement: if (x) free(x);
38+ bb = fc .getEnclosingStmt ( )
39+ or
40+ // Block statement with a single nested statement: if (x) { free(x); }
41+ strictcount ( bb .( BlockStmt ) .getAStmt ( ) ) = 1
42+ ) and
43+ strictcount ( BasicBlock bb2 | gc .ensuresEq ( _, 0 , bb2 , _) | bb2 ) = 1 and
44+ not fc .isInMacroExpansion ( ) and
45+ not blockContainsPreprocessorBranches ( bb ) and
46+ not ( gc instanceof BinaryOperation and not gc instanceof ComparisonOperation ) and
47+ not exists ( CommaExpr c | c .getAChild * ( ) = fc )
2648select gc , "unnecessary NULL check before call to $@" , fc , "free"
0 commit comments