Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libc/docs/dev/code_style.rst
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ this:
.. code-block:: c++

#include "src/__support/CPP/new.h"
#include "src/__support/alloc-checker.h"

...

Expand Down
31 changes: 23 additions & 8 deletions libc/src/__support/CPP/README.md
Original file line number Diff line number Diff line change
@@ -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`.
66 changes: 4 additions & 62 deletions libc/src/__support/CPP/new.h
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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

Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions libc/src/__support/File/dir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions libc/src/__support/File/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
3 changes: 2 additions & 1 deletion libc/src/__support/File/linux/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions libc/src/__support/HashTable/table.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
77 changes: 77 additions & 0 deletions libc/src/__support/alloc-checker.h
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions libc/src/__support/blockstore.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
1 change: 1 addition & 0 deletions libc/src/spawn/posix_spawn_file_actions_addclose.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions libc/src/spawn/posix_spawn_file_actions_adddup2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions libc/src/spawn/posix_spawn_file_actions_addopen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions libc/src/stdio/fopencookie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions libc/src/string/allocating_string_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
6 changes: 3 additions & 3 deletions libc/src/string/strndup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions libc/test/integration/src/pthread/pthread_create_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions libc/test/src/__support/File/file_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions libc/test/src/__support/hash_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading