diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt index 4e90aad9a45b4..5090dc218cda4 100644 --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -267,7 +267,9 @@ add_header_library( HDRS fixedvector.h DEPENDS + .libc_assert libc.src.__support.CPP.array + libc.src.string.memory_utils.inline_memset ) add_header_library( diff --git a/libc/src/__support/fixedvector.h b/libc/src/__support/fixedvector.h index 7ac0c230f9c53..34601f86dc017 100644 --- a/libc/src/__support/fixedvector.h +++ b/libc/src/__support/fixedvector.h @@ -10,9 +10,10 @@ #define LLVM_LIBC_SRC___SUPPORT_FIXEDVECTOR_H #include "src/__support/CPP/array.h" - #include "src/__support/CPP/iterator.h" +#include "src/__support/libc_assert.h" #include "src/__support/macros/config.h" +#include "src/string/memory_utils/inline_memset.h" namespace LIBC_NAMESPACE_DECL { @@ -23,27 +24,32 @@ template class FixedVector { size_t item_count = 0; public: - constexpr FixedVector() = default; + LIBC_INLINE constexpr FixedVector() = default; using iterator = typename cpp::array::iterator; - constexpr FixedVector(iterator begin, iterator end) : store{}, item_count{} { + LIBC_INLINE constexpr FixedVector(iterator begin, iterator end) + : store{}, item_count{} { + LIBC_ASSERT(begin + CAPACITY >= end); for (; begin != end; ++begin) push_back(*begin); } using const_iterator = typename cpp::array::const_iterator; - constexpr FixedVector(const_iterator begin, const_iterator end) + LIBC_INLINE constexpr FixedVector(const_iterator begin, const_iterator end) : store{}, item_count{} { + LIBC_ASSERT(begin + CAPACITY >= end); for (; begin != end; ++begin) push_back(*begin); } - constexpr FixedVector(size_t count, const T &value) : store{}, item_count{} { + LIBC_INLINE constexpr FixedVector(size_t count, const T &value) + : store{}, item_count{} { + LIBC_ASSERT(count <= CAPACITY); for (size_t i = 0; i < count; ++i) push_back(value); } - constexpr bool push_back(const T &obj) { + LIBC_INLINE constexpr bool push_back(const T &obj) { if (item_count == CAPACITY) return false; store[item_count] = obj; @@ -51,27 +57,43 @@ template class FixedVector { return true; } - constexpr const T &back() const { return store[item_count - 1]; } + LIBC_INLINE constexpr const T &back() const { + LIBC_ASSERT(!empty()); + return store[item_count - 1]; + } - constexpr T &back() { return store[item_count - 1]; } + LIBC_INLINE constexpr T &back() { + LIBC_ASSERT(!empty()); + return store[item_count - 1]; + } - constexpr bool pop_back() { + LIBC_INLINE constexpr bool pop_back() { if (item_count == 0) return false; + inline_memset(&store[item_count - 1], 0, sizeof(T)); --item_count; return true; } - constexpr T &operator[](size_t idx) { return store[idx]; } + LIBC_INLINE constexpr T &operator[](size_t idx) { + LIBC_ASSERT(idx < item_count); + return store[idx]; + } - constexpr const T &operator[](size_t idx) const { return store[idx]; } + LIBC_INLINE constexpr const T &operator[](size_t idx) const { + LIBC_ASSERT(idx < item_count); + return store[idx]; + } - constexpr bool empty() const { return item_count == 0; } + LIBC_INLINE constexpr bool empty() const { return item_count == 0; } - constexpr size_t size() const { return item_count; } + LIBC_INLINE constexpr size_t size() const { return item_count; } // Empties the store for all practical purposes. - constexpr void reset() { item_count = 0; } + LIBC_INLINE constexpr void reset() { + inline_memset(store.data(), 0, sizeof(T) * item_count); + item_count = 0; + } // This static method does not free up the resources held by |store|, // say by calling `free` or something similar. It just does the equivalent @@ -81,7 +103,9 @@ template class FixedVector { // dynamically allocated storate. So, the `destroy` method like this // matches the `destroy` API of those other data structures so that users // can easily swap one data structure for the other. - static void destroy(FixedVector *store) { store->reset(); } + LIBC_INLINE static void destroy(FixedVector *store) { + store->reset(); + } using reverse_iterator = typename cpp::array::reverse_iterator; LIBC_INLINE constexpr reverse_iterator rbegin() { diff --git a/libc/src/stdlib/exit_handler.h b/libc/src/stdlib/exit_handler.h index 9720c5473940e..e9d163dfe9024 100644 --- a/libc/src/stdlib/exit_handler.h +++ b/libc/src/stdlib/exit_handler.h @@ -48,7 +48,7 @@ LIBC_INLINE void stdc_at_exit_func(void *payload) { LIBC_INLINE void call_exit_callbacks(ExitCallbackList &callbacks) { handler_list_mtx.lock(); while (!callbacks.empty()) { - AtExitUnit &unit = callbacks.back(); + AtExitUnit unit = callbacks.back(); callbacks.pop_back(); handler_list_mtx.unlock(); unit.callback(unit.payload); diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 09811eb06ff02..ac3f5034d2bfa 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -670,6 +670,8 @@ libc_support_library( deps = [ ":__support_cpp_array", ":__support_cpp_iterator", + ":__support_libc_assert", + ":string_memory_utils", ], )