[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