]> granicus.if.org Git - clang/commitdiff
[analyzer] Malloc Checker: Report a leak when we are returning freed
authorAnna Zaks <ganna@apple.com>
Sat, 11 Feb 2012 21:44:39 +0000 (21:44 +0000)
committerAnna Zaks <ganna@apple.com>
Sat, 11 Feb 2012 21:44:39 +0000 (21:44 +0000)
memory.
(As per one test case, the existing checker thought that this could
cause a lot of false positives - not sure if that's valid, to be
verified.)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150313 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/MallocChecker.cpp
test/Analysis/malloc-annotations.c
test/Analysis/malloc.c

index d858959bd5da48e247cfdf32d2ddba501780bbbb..ea4d7d29eab8b0a9f8f15f150ad02f3ec9fa91d3 100644 (file)
@@ -760,10 +760,16 @@ void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
   const Expr *E = S->getRetValue();
   if (!E)
     return;
+
+  // Check if we are returning a symbol.
   SymbolRef Sym = C.getState()->getSVal(E, C.getLocationContext()).getAsSymbol();
   if (!Sym)
     return;
 
+  // Check if we are returning freed memory.
+  checkUseAfterFree(Sym, C, S);
+
+  // Check if the symbol is escaping.
   checkEscape(Sym, S, C);
 }
 
index 7890cfc1764268a83ac895514f6a9830f5026df4..98dc2e7269b303e53370cebce255df3be77decde 100644 (file)
@@ -128,12 +128,10 @@ void af3() {
   free(p); // no-warning
 }
 
-// This case would inflict a double-free elsewhere.
-// However, this case is considered an analyzer bug since it causes false-positives.
 int * af4() {
   int *p = my_malloc(12);
   my_free(p);
-  return p; // no-warning
+  return p; // expected-warning{{Use of dynamically allocated}}
 }
 
 // This case is (possibly) ok, be conservative
index 89299e6637d55b4b518baf83fcd28a1023b5951a..b3095e0f302a6b999c62b1f95459c6ef40145257 100644 (file)
@@ -251,6 +251,20 @@ void mallocFailedOrNot() {
 struct StructWithInt {
   int g;
 };
+
+int *mallocReturnFreed() {
+  int *p = malloc(12);
+  free(p);
+  return p; // expected-warning {{Use of dynamically allocated}}
+}
+
+int useAfterFreeStruct() {
+  struct StructWithInt *px= malloc(sizeof(struct StructWithInt));
+  px->g = 5;
+  free(px);
+  return px->g; // expected-warning {{Use of dynamically allocated}}
+}
+
 void nonSymbolAsFirstArg(int *pp, struct StructWithInt *p);
 
 void mallocEscapeFooNonSymbolArg() {