[Openmp-commits] [openmp] [clang] [OpenMP] Memory leaks in OpenMP when affinity is disabled (PR #225441)

Thomas Köppe via Openmp-commits openmp-commits at lists.llvm.org
Thu Sep 24 12:59:06 PDT 2026


https://github.com/tkoeppe updated https://github.com/llvm/llvm-project/pull/225441

>From f5090fcac3afa1ad0d8d1d604922aaf7b07eff39 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= <tkoeppe at google.com>
Date: Tue, 22 Sep 2026 16:48:44 +0100
Subject: [PATCH 1/3] [Clang][OpenMP] Don't call __kmp_allocate with zero
 argument.

Zero does not mean "size 0", but instead is a special sentiel value
meaning "affinity is disabled"
(https://github.com/llvm/llvm-project/blob/2643205b93aa72864b2ac0cd0ae8047bc8048baf/openmp/runtime/src/kmp.h#L672).

While it may not be entirely clear from the specs, the details of
__kmp_allocate ultimately imply that the "size" argument is required
to be strictly greater than zero.

Found by the ASAN leak sanitizer.
---
 openmp/runtime/src/kmp_affinity.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/openmp/runtime/src/kmp_affinity.h b/openmp/runtime/src/kmp_affinity.h
index fa69585f7e2d58..97b40fe360b6d2 100644
--- a/openmp/runtime/src/kmp_affinity.h
+++ b/openmp/runtime/src/kmp_affinity.h
@@ -350,7 +350,10 @@ class KMPNativeAffinity : public KMPAffinity {
 
   public:
     mask_t *mask;
-    Mask() { mask = (mask_t *)__kmp_allocate(__kmp_affin_mask_size); }
+    Mask()
+        : mask(__kmp_affin_mask_size == 0
+                   ? nullptr
+                   : (mask_t *)__kmp_allocate(__kmp_affin_mask_size)) {}
     ~Mask() {
       if (mask)
         __kmp_free(mask);

>From 685e385ccd0b5b1ba04ad7f56ba9bb09c0ef7283 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= <tkoeppe at google.com>
Date: Tue, 22 Sep 2026 16:53:40 +0100
Subject: [PATCH 2/3] [Clang][OpenMP] Missing cleanup before early return in
 __kmp_affinity_create_cpuinfo_map

Found by the ASAN leak sanitizer.
---
 openmp/runtime/src/kmp_affinity.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/openmp/runtime/src/kmp_affinity.cpp b/openmp/runtime/src/kmp_affinity.cpp
index 6a0e2910db8e09..31fe46be82cc23 100644
--- a/openmp/runtime/src/kmp_affinity.cpp
+++ b/openmp/runtime/src/kmp_affinity.cpp
@@ -3798,6 +3798,11 @@ static bool __kmp_affinity_create_cpuinfo_map(int *line,
   __kmp_ncores = totals[coreIdIndex];
   if (!KMP_AFFINITY_CAPABLE()) {
     KMP_ASSERT(__kmp_affinity.type == affinity_none);
+    __kmp_free(lastId);
+    __kmp_free(totals);
+    __kmp_free(maxCt);
+    __kmp_free(counts);
+    CLEANUP_THREAD_INFO;
     return true;
   }
 

>From d3cf6bd4951e501c4944f6d115dceae7b11a7dbd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= <tkoeppe at google.com>
Date: Wed, 23 Sep 2026 18:10:39 +0100
Subject: [PATCH 3/3] [Clang][OpenMP] Smoketest to show absence of (previous)
 memory leaks

---
 .../runtime/test/affinity/no_leak_with_disabled.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 openmp/runtime/test/affinity/no_leak_with_disabled.c

diff --git a/openmp/runtime/test/affinity/no_leak_with_disabled.c b/openmp/runtime/test/affinity/no_leak_with_disabled.c
new file mode 100644
index 00000000000000..2f0686af22e65d
--- /dev/null
+++ b/openmp/runtime/test/affinity/no_leak_with_disabled.c
@@ -0,0 +1,15 @@
+// RUN: %libomp-compile -fopenmp -fsanitize=hwaddress
+// RUN: %libomp-run
+// RUN: env KMP_AFFINITY=disabled %libomp-run
+
+// Check that no memory is leaked with KMP_AFFINITY=disabled.
+// The detection is done by ASAN/LSAN.
+
+#include <omp.h>
+
+int main(void) {
+#pragma omp parallel
+  {
+    omp_get_thread_num();
+  }
+}



More information about the Openmp-commits mailing list