[clang] [analyzer] [MallocChecker] Less aggressive analysis of functions (PR #116383)

via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 15 08:38:50 PST 2024


https://github.com/likeamahoney updated https://github.com/llvm/llvm-project/pull/116383

>From 92354e08433b3b683c59634d8f8e4d4d7dd3fd44 Mon Sep 17 00:00:00 2001
From: Yan Churkin <yan at ispras.ru>
Date: Fri, 15 Nov 2024 15:44:17 +0300
Subject: [PATCH 1/2] [analyzer] [MallocChecker] Less aggressive analysis of
 functions with the body

---
 .../StaticAnalyzer/Checkers/MallocChecker.cpp |  7 ++++
 clang/test/Analysis/malloc-interprocedural.c  | 38 ++++++++++++++++++-
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 4166cf14391e2d..80a24abc0d8fa7 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -3156,12 +3156,16 @@ void MallocChecker::checkPreCall(const CallEvent &Call,
     return;
   }
 
+  bool hasDef = false;
+
   // We will check for double free in the post visit.
   if (const AnyFunctionCall *FC = dyn_cast<AnyFunctionCall>(&Call)) {
     const FunctionDecl *FD = FC->getDecl();
     if (!FD)
       return;
 
+    hasDef = FD->getDefinition() != nullptr;
+
     if (ChecksEnabled[CK_MallocChecker] && isFreeingCall(Call))
       return;
   }
@@ -3173,6 +3177,9 @@ void MallocChecker::checkPreCall(const CallEvent &Call,
       return;
   }
 
+  if (ChecksEnabled[CK_MallocChecker] && !Call.isInSystemHeader() && hasDef)
+      return;
+
   // Check arguments for being used after free.
   for (unsigned I = 0, E = Call.getNumArgs(); I != E; ++I) {
     SVal ArgSVal = Call.getArgSVal(I);
diff --git a/clang/test/Analysis/malloc-interprocedural.c b/clang/test/Analysis/malloc-interprocedural.c
index 5e5232af7b46e8..b6979554a116d6 100644
--- a/clang/test/Analysis/malloc-interprocedural.c
+++ b/clang/test/Analysis/malloc-interprocedural.c
@@ -26,7 +26,7 @@ static void *my_malloc2(int elevel, size_t size) {
 }
 
 static void my_free1(void *p) {
-  free(p);
+  free(p); // expected-warning {{Attempt to free released memory}}
 }
 
 static void test1(void) {
@@ -65,7 +65,7 @@ int test4(void) {
 void test6(void) {
   int *data = (int *)my_malloc2(1, 4);
   my_free1((int*)data);
-  my_free1((int*)data); // expected-warning{{Use of memory after it is freed}}
+  my_free1((int*)data);
 }
 
 // TODO: We should warn here.
@@ -98,3 +98,37 @@ int uafAndCallsFooWithEmptyReturn(void) {
   fooWithEmptyReturn(12);
   return *x; // expected-warning {{Use of memory after it is freed}}
 }
+
+static void test_empty(int *p) { return; }
+
+void test7() {
+  int *p = malloc(sizeof(int));
+  free(p);
+
+  test_empty(p); // no-warning
+}
+
+static void test_realloc(int *p) {
+  p = (int *)malloc(12);
+  free(p);
+  return;
+}
+
+void test8() {
+  int *p = malloc(sizeof(int));
+  free(p);
+
+  test_realloc(p); // no-warning
+}
+
+static void test_interproc_ptr_use(int *p) {
+  *p = 1; // expected-warning {{Use of memory after it is freed}}
+  return;
+}
+
+void test9() {
+  int *p = malloc(sizeof(int));
+  free(p);
+
+  test_interproc_ptr_use(p);
+}

>From 8f63b3fa53dfcee92a23c2117b23444d99053b76 Mon Sep 17 00:00:00 2001
From: Yan Churkin <yan at ispras.ru>
Date: Fri, 15 Nov 2024 19:32:25 +0300
Subject: [PATCH 2/2] Fix naming

---
 clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 80a24abc0d8fa7..71a66f3ad2544a 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -3156,7 +3156,7 @@ void MallocChecker::checkPreCall(const CallEvent &Call,
     return;
   }
 
-  bool hasDef = false;
+  bool HasDef = false;
 
   // We will check for double free in the post visit.
   if (const AnyFunctionCall *FC = dyn_cast<AnyFunctionCall>(&Call)) {
@@ -3164,7 +3164,7 @@ void MallocChecker::checkPreCall(const CallEvent &Call,
     if (!FD)
       return;
 
-    hasDef = FD->getDefinition() != nullptr;
+    HasDef = FD->getDefinition() != nullptr;
 
     if (ChecksEnabled[CK_MallocChecker] && isFreeingCall(Call))
       return;
@@ -3177,8 +3177,8 @@ void MallocChecker::checkPreCall(const CallEvent &Call,
       return;
   }
 
-  if (ChecksEnabled[CK_MallocChecker] && !Call.isInSystemHeader() && hasDef)
-      return;
+  if (ChecksEnabled[CK_MallocChecker] && !Call.isInSystemHeader() && HasDef)
+    return;
 
   // Check arguments for being used after free.
   for (unsigned I = 0, E = Call.getNumArgs(); I != E; ++I) {



More information about the cfe-commits mailing list