[libc-commits] [libc] [libc] Split out src/__support/alloc-checker.h (PR #173104)
via libc-commits
libc-commits at lists.llvm.org
Fri Dec 19 13:37:16 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Roland McGrath (frobtech)
<details>
<summary>Changes</summary>
This moves the libc-internal AllocChecker API out of
src/__support/CPP/new.h and updates CPP/README.md to state the
intent to keep src/__support/CPP and the LIBC_NAMESPACE::cpp
namespace a "pure" subset of standard C++ API polyfills.
---
Full diff: https://github.com/llvm/llvm-project/pull/173104.diff
18 Files Affected:
- (modified) libc/docs/dev/code_style.rst (+1)
- (modified) libc/src/__support/CPP/README.md (+23-8)
- (modified) libc/src/__support/CPP/new.h (+4-62)
- (modified) libc/src/__support/File/dir.cpp (+1)
- (modified) libc/src/__support/File/file.cpp (+1)
- (modified) libc/src/__support/File/linux/file.cpp (+2-1)
- (modified) libc/src/__support/HashTable/table.h (+1)
- (added) libc/src/__support/alloc-checker.h (+77)
- (modified) libc/src/__support/blockstore.h (+1)
- (modified) libc/src/spawn/posix_spawn_file_actions_addclose.cpp (+1)
- (modified) libc/src/spawn/posix_spawn_file_actions_adddup2.cpp (+1)
- (modified) libc/src/spawn/posix_spawn_file_actions_addopen.cpp (+1)
- (modified) libc/src/stdio/fopencookie.cpp (+1)
- (modified) libc/src/string/allocating_string_utils.h (+1)
- (modified) libc/src/string/strndup.cpp (+3-3)
- (modified) libc/test/integration/src/pthread/pthread_create_test.cpp (+1)
- (modified) libc/test/src/__support/File/file_test.cpp (+2-2)
- (modified) libc/test/src/__support/hash_test.cpp (+1)
``````````diff
diff --git a/libc/docs/dev/code_style.rst b/libc/docs/dev/code_style.rst
index 5eafff9ef9b3d..f88d82feea367 100644
--- a/libc/docs/dev/code_style.rst
+++ b/libc/docs/dev/code_style.rst
@@ -159,6 +159,7 @@ this:
.. code-block:: c++
#include "src/__support/CPP/new.h"
+ #include "src/__support/alloc-checker.h"
...
diff --git a/libc/src/__support/CPP/README.md b/libc/src/__support/CPP/README.md
index b470c3f1dc343..70e2939a33653 100644
--- a/libc/src/__support/CPP/README.md
+++ b/libc/src/__support/CPP/README.md
@@ -1,13 +1,28 @@
This directory contains partial re-implementations of some C++ standard library
utilities. They are for use with internal LLVM libc code and tests.
-More utilities can be added on an as needed basis. There are certain rules to
+More utilities can be added on an as-needed basis. There are certain rules to
be followed for future changes and additions:
-1. Only two kind of headers can be included: Other headers from this directory,
-and free standing C headers.
-2. Free standing C headers are to be included as C headers and not as C++
-headers. That is, use `#include <stddef.h>` and not `#include <cstddef>`.
-3. The utilities should be defined in the namespace `LIBC_NAMESPACE::cpp`. The
-higher level namespace should have a `__` prefix to avoid symbol name pollution
-when the utilities are used in implementation of public functions.
+* Only certain kind of headers can be included:
+ * Other headers from this directory
+ * Free-standing C headers (`<stdint.h>` et al)
+ * A few basic `src/__support/macros` headers used pervasively in all libc code
+
+ * Free-standing C headers are to be included as C headers and not as C++
+ headers. That is, use `#include <stddef.h>` and not `#include <cstddef>`.
+ The [proxies](../../../hdr) can also be used, as in `#include "hdr/stdint_proxy.h"`.
+
+* The utilities should be defined in the namespace `LIBC_NAMESPACE::cpp`. The
+ higher level namespace should have a `__` prefix to avoid symbol name pollution
+ when the utilities are used in implementation of public functions.
+
+* Each "CPP/foo.h" provides an exact subset of the API from standard C++ <foo>,
+ just using `LIBC_NAMESPACE::cpp::foo` names in place of `std::foo` names. The
+ implementations here need not be perfect standard-conforming implementations,
+ but their behavior must match for whatever _is_ supported at compile time.
+ That is, if each were just declared with `using std::foo;` all the libc code
+ should work the same (functionally speaking, excluding namespace entanglements).
+
+* Additional APIs specific to libc internals belong elsewhere in `src/__support`,
+ not in `src/__support/CPP`.
diff --git a/libc/src/__support/CPP/new.h b/libc/src/__support/CPP/new.h
index 67344b09e3833..e529e05d858a4 100644
--- a/libc/src/__support/CPP/new.h
+++ b/libc/src/__support/CPP/new.h
@@ -1,4 +1,4 @@
-//===-- Libc specific custom operator new and delete ------------*- C++ -*-===//
+//===-- Libc-internal alternative to <new> ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,13 +9,10 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_NEW_H
#define LLVM_LIBC_SRC___SUPPORT_CPP_NEW_H
-#include "hdr/func/aligned_alloc.h"
#include "hdr/func/free.h"
-#include "hdr/func/malloc.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/compiler.h"
-#include "src/__support/macros/properties/os.h"
#include <stddef.h> // For size_t
@@ -29,78 +26,23 @@ enum class align_val_t : size_t {};
} // namespace std
namespace LIBC_NAMESPACE_DECL {
-
namespace cpp {
+
template <class T> [[nodiscard]] constexpr T *launder(T *p) {
static_assert(__has_builtin(__builtin_launder),
"cpp::launder requires __builtin_launder");
return __builtin_launder(p);
}
-} // namespace cpp
-
-class AllocChecker {
- bool success = false;
-
- LIBC_INLINE AllocChecker &operator=(bool status) {
- success = status;
- return *this;
- }
-
-public:
- LIBC_INLINE AllocChecker() = default;
-
- LIBC_INLINE operator bool() const { return success; }
-
- LIBC_INLINE static void *alloc(size_t s, AllocChecker &ac) {
- void *mem = ::malloc(s);
- ac = (mem != nullptr);
- return mem;
- }
-
- LIBC_INLINE static void *aligned_alloc(size_t s, std::align_val_t align,
- AllocChecker &ac) {
-#ifdef LIBC_TARGET_OS_IS_WINDOWS
- // std::aligned_alloc is not available on Windows because std::free on
- // Windows cannot deallocate any over-aligned memory. Microsoft provides an
- // alternative for std::aligned_alloc named _aligned_malloc, but it must be
- // paired with _aligned_free instead of std::free.
- void *mem = ::_aligned_malloc(static_cast<size_t>(align), s);
-#else
- void *mem = ::aligned_alloc(static_cast<size_t>(align), s);
-#endif
- ac = (mem != nullptr);
- return mem;
- }
-};
+} // namespace cpp
} // namespace LIBC_NAMESPACE_DECL
-LIBC_INLINE void *operator new(size_t size,
- LIBC_NAMESPACE::AllocChecker &ac) noexcept {
- return LIBC_NAMESPACE::AllocChecker::alloc(size, ac);
-}
-
-LIBC_INLINE void *operator new(size_t size, std::align_val_t align,
- LIBC_NAMESPACE::AllocChecker &ac) noexcept {
- return LIBC_NAMESPACE::AllocChecker::aligned_alloc(size, align, ac);
-}
-
-LIBC_INLINE void *operator new[](size_t size,
- LIBC_NAMESPACE::AllocChecker &ac) noexcept {
- return LIBC_NAMESPACE::AllocChecker::alloc(size, ac);
-}
-
-LIBC_INLINE void *operator new[](size_t size, std::align_val_t align,
- LIBC_NAMESPACE::AllocChecker &ac) noexcept {
- return LIBC_NAMESPACE::AllocChecker::aligned_alloc(size, align, ac);
-}
-
LIBC_INLINE void *operator new(size_t, void *p) { return p; }
LIBC_INLINE void *operator new[](size_t, void *p) { return p; }
// The ideal situation would be to define the various flavors of operator delete
-// inlinelike we do with operator new above. However, since we need operator
+// inline like we do with operator new above. However, since we need operator
// delete prototypes to match those specified by the C++ standard, we cannot
// define them inline as the C++ standard does not allow inline definitions of
// replacement operator delete implementations. Note also that we assign a
diff --git a/libc/src/__support/File/dir.cpp b/libc/src/__support/File/dir.cpp
index aea8862c15f7f..eb33656808414 100644
--- a/libc/src/__support/File/dir.cpp
+++ b/libc/src/__support/File/dir.cpp
@@ -10,6 +10,7 @@
#include "src/__support/CPP/mutex.h" // lock_guard
#include "src/__support/CPP/new.h"
+#include "src/__support/alloc-checker.h"
#include "src/__support/error_or.h"
#include "src/__support/libc_errno.h" // For error macros
#include "src/__support/macros/config.h"
diff --git a/libc/src/__support/File/file.cpp b/libc/src/__support/File/file.cpp
index 15ec1a23e2b8d..ccc7acf9387f5 100644
--- a/libc/src/__support/File/file.cpp
+++ b/libc/src/__support/File/file.cpp
@@ -13,6 +13,7 @@
#include "hdr/types/off_t.h"
#include "src/__support/CPP/new.h"
#include "src/__support/CPP/span.h"
+#include "src/__support/alloc-checker.h"
#include "src/__support/libc_errno.h" // For error macros
#include "src/__support/macros/config.h"
#include "src/string/memory_utils/inline_memcpy.h"
diff --git a/libc/src/__support/File/linux/file.cpp b/libc/src/__support/File/linux/file.cpp
index 4594dadf1ccdf..28f819db83d49 100644
--- a/libc/src/__support/File/linux/file.cpp
+++ b/libc/src/__support/File/linux/file.cpp
@@ -15,7 +15,8 @@
#include "src/__support/File/linux/lseekImpl.h"
#include "src/__support/OSUtil/fcntl.h"
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
-#include "src/__support/libc_errno.h" // For error macros
+#include "src/__support/alloc-checker.h"
+#include "src/__support/libc_errno.h" // For error macros
#include "src/__support/macros/config.h"
#include "hdr/fcntl_macros.h" // For mode_t and other flags to the open syscall
diff --git a/libc/src/__support/HashTable/table.h b/libc/src/__support/HashTable/table.h
index 966ee0fcaf0ae..f42eead2efcf2 100644
--- a/libc/src/__support/HashTable/table.h
+++ b/libc/src/__support/HashTable/table.h
@@ -14,6 +14,7 @@
#include "src/__support/CPP/bit.h" // bit_ceil
#include "src/__support/CPP/new.h"
#include "src/__support/HashTable/bitmask.h"
+#include "src/__support/alloc-checker.h"
#include "src/__support/hash.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
diff --git a/libc/src/__support/alloc-checker.h b/libc/src/__support/alloc-checker.h
new file mode 100644
index 0000000000000..ecef094453cc8
--- /dev/null
+++ b/libc/src/__support/alloc-checker.h
@@ -0,0 +1,77 @@
+//===-- Libc specific custom operator new and delete ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_ALLOC_CHECKER_H
+#define LLVM_LIBC_SRC___SUPPORT_ALLOC_CHECKER_H
+
+#include "hdr/func/aligned_alloc.h"
+#include "hdr/func/malloc.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/os.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+class AllocChecker {
+ bool success = false;
+
+ LIBC_INLINE AllocChecker &operator=(bool status) {
+ success = status;
+ return *this;
+ }
+
+public:
+ LIBC_INLINE AllocChecker() = default;
+
+ LIBC_INLINE operator bool() const { return success; }
+
+ LIBC_INLINE static void *alloc(size_t s, AllocChecker &ac) {
+ void *mem = ::malloc(s);
+ ac = (mem != nullptr);
+ return mem;
+ }
+
+ LIBC_INLINE static void *aligned_alloc(size_t s, std::align_val_t align,
+ AllocChecker &ac) {
+#ifdef LIBC_TARGET_OS_IS_WINDOWS
+ // std::aligned_alloc is not available on Windows because std::free on
+ // Windows cannot deallocate any over-aligned memory. Microsoft provides an
+ // alternative for std::aligned_alloc named _aligned_malloc, but it must be
+ // paired with _aligned_free instead of std::free.
+ void *mem = ::_aligned_malloc(static_cast<size_t>(align), s);
+#else
+ void *mem = ::aligned_alloc(static_cast<size_t>(align), s);
+#endif
+ ac = (mem != nullptr);
+ return mem;
+ }
+};
+
+} // namespace LIBC_NAMESPACE_DECL
+
+LIBC_INLINE void *operator new(size_t size,
+ LIBC_NAMESPACE::AllocChecker &ac) noexcept {
+ return LIBC_NAMESPACE::AllocChecker::alloc(size, ac);
+}
+
+LIBC_INLINE void *operator new(size_t size, std::align_val_t align,
+ LIBC_NAMESPACE::AllocChecker &ac) noexcept {
+ return LIBC_NAMESPACE::AllocChecker::aligned_alloc(size, align, ac);
+}
+
+LIBC_INLINE void *operator new[](size_t size,
+ LIBC_NAMESPACE::AllocChecker &ac) noexcept {
+ return LIBC_NAMESPACE::AllocChecker::alloc(size, ac);
+}
+
+LIBC_INLINE void *operator new[](size_t size, std::align_val_t align,
+ LIBC_NAMESPACE::AllocChecker &ac) noexcept {
+ return LIBC_NAMESPACE::AllocChecker::aligned_alloc(size, align, ac);
+}
+
+#endif // LLVM_LIBC_SRC___SUPPORT_ALLOC_CHECKER_H
diff --git a/libc/src/__support/blockstore.h b/libc/src/__support/blockstore.h
index 61ee0ee80a2bf..af84262222c60 100644
--- a/libc/src/__support/blockstore.h
+++ b/libc/src/__support/blockstore.h
@@ -13,6 +13,7 @@
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/new.h"
#include "src/__support/CPP/type_traits.h"
+#include "src/__support/alloc-checker.h"
#include "src/__support/libc_assert.h"
#include "src/__support/macros/config.h"
diff --git a/libc/src/spawn/posix_spawn_file_actions_addclose.cpp b/libc/src/spawn/posix_spawn_file_actions_addclose.cpp
index 9a575bd591632..04213a82ec726 100644
--- a/libc/src/spawn/posix_spawn_file_actions_addclose.cpp
+++ b/libc/src/spawn/posix_spawn_file_actions_addclose.cpp
@@ -10,6 +10,7 @@
#include "file_actions.h"
#include "src/__support/CPP/new.h"
+#include "src/__support/alloc-checker.h"
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
diff --git a/libc/src/spawn/posix_spawn_file_actions_adddup2.cpp b/libc/src/spawn/posix_spawn_file_actions_adddup2.cpp
index 1ad45ed942bb9..569fc20e73d60 100644
--- a/libc/src/spawn/posix_spawn_file_actions_adddup2.cpp
+++ b/libc/src/spawn/posix_spawn_file_actions_adddup2.cpp
@@ -10,6 +10,7 @@
#include "file_actions.h"
#include "src/__support/CPP/new.h"
+#include "src/__support/alloc-checker.h"
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
diff --git a/libc/src/spawn/posix_spawn_file_actions_addopen.cpp b/libc/src/spawn/posix_spawn_file_actions_addopen.cpp
index 9977fc2d0a218..23a8907596932 100644
--- a/libc/src/spawn/posix_spawn_file_actions_addopen.cpp
+++ b/libc/src/spawn/posix_spawn_file_actions_addopen.cpp
@@ -10,6 +10,7 @@
#include "file_actions.h"
#include "src/__support/CPP/new.h"
+#include "src/__support/alloc-checker.h"
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
diff --git a/libc/src/stdio/fopencookie.cpp b/libc/src/stdio/fopencookie.cpp
index da8a132a4db6e..dafc7823e5fd9 100644
--- a/libc/src/stdio/fopencookie.cpp
+++ b/libc/src/stdio/fopencookie.cpp
@@ -13,6 +13,7 @@
#include "hdr/types/off_t.h"
#include "src/__support/CPP/new.h"
#include "src/__support/File/file.h"
+#include "src/__support/alloc-checker.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
diff --git a/libc/src/string/allocating_string_utils.h b/libc/src/string/allocating_string_utils.h
index e2f61f77b0c75..dfaa794298889 100644
--- a/libc/src/string/allocating_string_utils.h
+++ b/libc/src/string/allocating_string_utils.h
@@ -11,6 +11,7 @@
#include "src/__support/CPP/new.h"
#include "src/__support/CPP/optional.h"
+#include "src/__support/alloc-checker.h"
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
#include "src/string/memory_utils/inline_memcpy.h"
#include "src/string/string_utils.h"
diff --git a/libc/src/string/strndup.cpp b/libc/src/string/strndup.cpp
index b19d7c060baa1..40f473a0167fe 100644
--- a/libc/src/string/strndup.cpp
+++ b/libc/src/string/strndup.cpp
@@ -7,13 +7,13 @@
//===----------------------------------------------------------------------===//
#include "src/string/strndup.h"
+#include "src/__support/CPP/new.h"
+#include "src/__support/alloc-checker.h"
+#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/string/memory_utils/inline_memcpy.h"
#include "src/string/string_utils.h"
-#include "src/__support/CPP/new.h"
-#include "src/__support/common.h"
-
#include <stddef.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/test/integration/src/pthread/pthread_create_test.cpp b/libc/test/integration/src/pthread/pthread_create_test.cpp
index d436cc3270d9c..6fae8e747a204 100644
--- a/libc/test/integration/src/pthread/pthread_create_test.cpp
+++ b/libc/test/integration/src/pthread/pthread_create_test.cpp
@@ -27,6 +27,7 @@
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/atomic.h"
#include "src/__support/CPP/new.h"
+#include "src/__support/alloc-checker.h"
#include "src/__support/threads/thread.h"
#include "test/IntegrationTest/test.h"
diff --git a/libc/test/src/__support/File/file_test.cpp b/libc/test/src/__support/File/file_test.cpp
index 17dad4d5ac917..ed2200b879048 100644
--- a/libc/test/src/__support/File/file_test.cpp
+++ b/libc/test/src/__support/File/file_test.cpp
@@ -6,14 +6,14 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/types/size_t.h"
#include "src/__support/CPP/new.h"
#include "src/__support/File/file.h"
+#include "src/__support/alloc-checker.h"
#include "src/__support/error_or.h"
#include "test/UnitTest/MemoryMatcher.h"
#include "test/UnitTest/Test.h"
-#include "hdr/types/size_t.h"
-
using ModeFlags = LIBC_NAMESPACE::File::ModeFlags;
using MemoryView = LIBC_NAMESPACE::testing::MemoryView;
using LIBC_NAMESPACE::ErrorOr;
diff --git a/libc/test/src/__support/hash_test.cpp b/libc/test/src/__support/hash_test.cpp
index 94c884cc7fb17..417a43a58b340 100644
--- a/libc/test/src/__support/hash_test.cpp
+++ b/libc/test/src/__support/hash_test.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/CPP/new.h"
+#include "src/__support/alloc-checker.h"
#include "src/__support/hash.h"
#include "src/stdlib/rand.h"
#include "src/stdlib/srand.h"
``````````
</details>
https://github.com/llvm/llvm-project/pull/173104
More information about the libc-commits
mailing list