[libc-commits] [libc] [libc][CPP][NFC] Remove unused cpp::vector container (PR #224976)
via libc-commits
libc-commits at lists.llvm.org
Sun Sep 20 16:00:17 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Jeff Bailey (kaladron)
<details>
<summary>Changes</summary>
Removed cpp::vector (added in 5afbbd04803c) and its unit tests.
The group and password database entrypoints now pack auxiliary pointer arrays into the trailing scratch space of DynamicBuffer (7252edd9aa82), leaving cpp::vector with no callers in the codebase.
Assisted-by: Automated tooling, human reviewed.
---
Full diff: https://github.com/llvm/llvm-project/pull/224976.diff
4 Files Affected:
- (modified) libc/src/__support/CPP/CMakeLists.txt (-17)
- (removed) libc/src/__support/CPP/vector.h (-309)
- (modified) libc/test/src/__support/CPP/CMakeLists.txt (-12)
- (removed) libc/test/src/__support/CPP/vector_test.cpp (-302)
``````````diff
diff --git a/libc/src/__support/CPP/CMakeLists.txt b/libc/src/__support/CPP/CMakeLists.txt
index 16d9db567abf4..6777c6a27c0cc 100644
--- a/libc/src/__support/CPP/CMakeLists.txt
+++ b/libc/src/__support/CPP/CMakeLists.txt
@@ -253,20 +253,3 @@ add_header_library(
.utility
.tuple
)
-
-add_header_library(
- vector
- HDRS
- vector.h
- DEPENDS
- .new
- .type_traits
- .utility
- libc.hdr.func.free
- libc.hdr.func.malloc
- libc.hdr.func.realloc
- libc.hdr.types.size_t
- libc.src.__support.common
- libc.src.__support.libc_assert
- libc.src.__support.macros.config
-)
diff --git a/libc/src/__support/CPP/vector.h b/libc/src/__support/CPP/vector.h
deleted file mode 100644
index 839a937505671..0000000000000
--- a/libc/src/__support/CPP/vector.h
+++ /dev/null
@@ -1,309 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// Implementation of vector container.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_VECTOR_H
-#define LLVM_LIBC_SRC___SUPPORT_CPP_VECTOR_H
-
-#include "hdr/func/free.h"
-#include "hdr/func/malloc.h"
-#include "hdr/func/realloc.h"
-#include "hdr/types/size_t.h"
-#include "src/__support/CPP/new.h"
-#include "src/__support/CPP/type_traits.h"
-#include "src/__support/CPP/utility.h"
-#include "src/__support/common.h"
-#include "src/__support/libc_assert.h"
-#include "src/__support/macros/config.h"
-
-#include <stddef.h> // For max_align_t, ptrdiff_t
-
-namespace LIBC_NAMESPACE_DECL {
-namespace cpp {
-
-template <typename T> class vector {
- static_assert(alignof(T) <= alignof(max_align_t),
- "Overaligned types are not supported by cpp::vector");
-
-public:
- using value_type = T;
- using size_type = size_t;
- using difference_type = ptrdiff_t;
- using reference = T &;
- using const_reference = const T &;
- using pointer = T *;
- using const_pointer = const T *;
- using iterator = T *;
- using const_iterator = const T *;
-
- [[nodiscard]] LIBC_INLINE constexpr size_type max_size() const noexcept {
- return static_cast<size_type>(-1) / sizeof(T);
- }
-
-private:
- T *data_ = nullptr;
- size_t size_ = 0;
- size_t capacity_ = 0;
-
- static constexpr size_t DEFAULT_INITIAL_CAPACITY = 16;
-
- LIBC_INLINE void destroy_elements(size_t from, size_t to) {
- if constexpr (!is_trivially_destructible_v<T>) {
- while (to > from) {
- --to;
- data_[to].~T();
- }
- }
- }
-
- LIBC_INLINE void deallocate() {
- if (data_) {
- destroy_elements(0, size_);
- ::free(data_);
- data_ = nullptr;
- size_ = 0;
- capacity_ = 0;
- }
- }
-
- [[nodiscard]] LIBC_INLINE bool reallocate(size_t new_cap) {
- if constexpr (is_trivially_copyable_v<T>) {
- void *new_data = ::realloc(data_, new_cap * sizeof(T));
- if (!new_data)
- return false;
- data_ = static_cast<T *>(new_data);
- capacity_ = new_cap;
- return true;
- } else {
- void *new_raw = ::malloc(new_cap * sizeof(T));
- if (!new_raw)
- return false;
- T *new_data = static_cast<T *>(new_raw);
- for (size_t i = 0; i < size_; ++i) {
- new (new_data + i) T(cpp::move(data_[i]));
- data_[i].~T();
- }
- ::free(data_);
- data_ = new_data;
- capacity_ = new_cap;
- return true;
- }
- }
-
-public:
- LIBC_INLINE constexpr vector() = default;
-
- LIBC_INLINE ~vector() { deallocate(); }
-
- // Move constructor
- LIBC_INLINE vector(vector &&other) noexcept
- : data_(other.data_), size_(other.size_), capacity_(other.capacity_) {
- other.data_ = nullptr;
- other.size_ = 0;
- other.capacity_ = 0;
- }
-
- // Move assignment
- LIBC_INLINE vector &operator=(vector &&other) noexcept {
- if (this != &other) {
- deallocate();
- data_ = other.data_;
- size_ = other.size_;
- capacity_ = other.capacity_;
- other.data_ = nullptr;
- other.size_ = 0;
- other.capacity_ = 0;
- }
- return *this;
- }
-
- // Copy operations are deleted to prevent accidental implicit allocations.
- vector(const vector &) = delete;
- vector &operator=(const vector &) = delete;
-
- // Element access
- [[nodiscard]] LIBC_INLINE reference operator[](size_t i) {
- LIBC_ASSERT(i < size_);
- return data_[i];
- }
-
- [[nodiscard]] LIBC_INLINE const_reference operator[](size_t i) const {
- LIBC_ASSERT(i < size_);
- return data_[i];
- }
-
- [[nodiscard]] LIBC_INLINE pointer data() { return data_; }
- [[nodiscard]] LIBC_INLINE const_pointer data() const { return data_; }
-
- [[nodiscard]] LIBC_INLINE reference front() {
- LIBC_ASSERT(size_ > 0);
- return data_[0];
- }
-
- [[nodiscard]] LIBC_INLINE const_reference front() const {
- LIBC_ASSERT(size_ > 0);
- return data_[0];
- }
-
- [[nodiscard]] LIBC_INLINE reference back() {
- LIBC_ASSERT(size_ > 0);
- return data_[size_ - 1];
- }
-
- [[nodiscard]] LIBC_INLINE const_reference back() const {
- LIBC_ASSERT(size_ > 0);
- return data_[size_ - 1];
- }
-
- // Iterators
- [[nodiscard]] LIBC_INLINE iterator begin() { return data_; }
- [[nodiscard]] LIBC_INLINE const_iterator begin() const { return data_; }
- [[nodiscard]] LIBC_INLINE const_iterator cbegin() const { return data_; }
- [[nodiscard]] LIBC_INLINE iterator end() { return data_ + size_; }
- [[nodiscard]] LIBC_INLINE const_iterator end() const { return data_ + size_; }
- [[nodiscard]] LIBC_INLINE const_iterator cend() const {
- return data_ + size_;
- }
-
- // Capacity
- [[nodiscard]] LIBC_INLINE bool empty() const { return size_ == 0; }
- [[nodiscard]] LIBC_INLINE size_t size() const { return size_; }
- [[nodiscard]] LIBC_INLINE size_t capacity() const { return capacity_; }
-
- // Reserves at least new_cap elements. Returns true on success, false on OOM.
- [[nodiscard]] LIBC_INLINE bool reserve(size_t new_cap) {
- if (new_cap <= capacity_)
- return true;
- if (new_cap > max_size())
- return false;
- return reallocate(new_cap);
- }
-
- LIBC_INLINE void shrink_to_fit() {
- if (size_ == capacity_)
- return;
- if (size_ == 0) {
- reset();
- return;
- }
- static_cast<void>(reallocate(size_));
- }
-
- // Modifiers
- template <typename... Args>
- [[nodiscard]] LIBC_INLINE bool emplace_back(Args &&...args) {
- if (size_ < capacity_) {
- new (data_ + size_) T(cpp::forward<Args>(args)...);
- ++size_;
- return true;
- }
-
- size_t new_cap = DEFAULT_INITIAL_CAPACITY;
- if (capacity_ > 0) {
- if (capacity_ > max_size() / 2)
- return false;
- new_cap = capacity_ * 2;
- }
-
- void *new_raw = ::malloc(new_cap * sizeof(T));
- if (!new_raw)
- return false;
- T *new_data = static_cast<T *>(new_raw);
-
- // Construct the new element before moving/freeing old storage so that
- // arguments referencing the vector's own buffer remain valid.
- new (new_data + size_) T(cpp::forward<Args>(args)...);
-
- for (size_t i = 0; i < size_; ++i) {
- new (new_data + i) T(cpp::move(data_[i]));
- data_[i].~T();
- }
- ::free(data_);
- data_ = new_data;
- capacity_ = new_cap;
- ++size_;
- return true;
- }
-
- [[nodiscard]] LIBC_INLINE bool push_back(const T &val) {
- return emplace_back(val);
- }
-
- [[nodiscard]] LIBC_INLINE bool push_back(T &&val) {
- return emplace_back(cpp::move(val));
- }
-
- LIBC_INLINE void pop_back() {
- LIBC_ASSERT(size_ > 0);
- --size_;
- if constexpr (!is_trivially_destructible_v<T>)
- data_[size_].~T();
- }
-
- LIBC_INLINE void clear() {
- destroy_elements(0, size_);
- size_ = 0;
- }
-
- // Deallocates backing memory and resets size and capacity to 0.
- LIBC_INLINE void reset() { deallocate(); }
-
- [[nodiscard]] LIBC_INLINE bool resize(size_t new_size) {
- if (new_size < size_) {
- destroy_elements(new_size, size_);
- size_ = new_size;
- return true;
- }
- if (new_size > size_) {
- if (!reserve(new_size))
- return false;
- for (size_t i = size_; i < new_size; ++i)
- new (data_ + i) T();
- size_ = new_size;
- }
- return true;
- }
-
- [[nodiscard]] LIBC_INLINE bool resize(size_t new_size, const T &value) {
- if (new_size < size_) {
- destroy_elements(new_size, size_);
- size_ = new_size;
- return true;
- }
- if (new_size > size_) {
- // Copy value before reserve in case value references this vector's data.
- T val_copy(value);
- if (!reserve(new_size))
- return false;
- for (size_t i = size_; i < new_size; ++i)
- new (data_ + i) T(val_copy);
- size_ = new_size;
- }
- return true;
- }
-
- LIBC_INLINE void swap(vector &other) noexcept {
- cpp::swap(data_, other.data_);
- cpp::swap(size_, other.size_);
- cpp::swap(capacity_, other.capacity_);
- }
-};
-
-template <typename T>
-LIBC_INLINE void swap(vector<T> &lhs, vector<T> &rhs) noexcept {
- lhs.swap(rhs);
-}
-
-} // namespace cpp
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC___SUPPORT_CPP_VECTOR_H
diff --git a/libc/test/src/__support/CPP/CMakeLists.txt b/libc/test/src/__support/CPP/CMakeLists.txt
index 7931da87fca14..e962487a87a43 100644
--- a/libc/test/src/__support/CPP/CMakeLists.txt
+++ b/libc/test/src/__support/CPP/CMakeLists.txt
@@ -207,18 +207,6 @@ add_libc_test(
libc.src.__support.CPP.type_traits
)
-add_libc_test(
- vector_test
- SUITE
- libc-cpp-utils-tests
- SRCS
- vector_test.cpp
- DEPENDS
- libc.src.__support.CPP.type_traits
- libc.src.__support.CPP.utility
- libc.src.__support.CPP.vector
-)
-
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
add_libc_test(
simd_test
diff --git a/libc/test/src/__support/CPP/vector_test.cpp b/libc/test/src/__support/CPP/vector_test.cpp
deleted file mode 100644
index 036e64b9156ea..0000000000000
--- a/libc/test/src/__support/CPP/vector_test.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// Unit tests for vector.
-///
-//===----------------------------------------------------------------------===//
-
-#include "src/__support/CPP/vector.h"
-#include "test/UnitTest/Test.h"
-
-using LIBC_NAMESPACE::cpp::vector;
-
-TEST(LlvmLibcVectorTest, InitializeEmpty) {
- vector<int> v;
- EXPECT_TRUE(v.empty());
- EXPECT_EQ(v.size(), size_t(0));
- EXPECT_EQ(v.capacity(), size_t(0));
- EXPECT_EQ(v.data(), static_cast<int *>(nullptr));
-}
-
-TEST(LlvmLibcVectorTest, PushBackAndAccess) {
- vector<int> v;
- ASSERT_TRUE(v.push_back(10));
- ASSERT_TRUE(v.push_back(20));
- ASSERT_TRUE(v.push_back(30));
-
- EXPECT_FALSE(v.empty());
- EXPECT_EQ(v.size(), size_t(3));
- EXPECT_GE(v.capacity(), size_t(3));
-
- EXPECT_EQ(v[0], 10);
- EXPECT_EQ(v[1], 20);
- EXPECT_EQ(v[2], 30);
- EXPECT_EQ(v.front(), 10);
- EXPECT_EQ(v.back(), 30);
- ASSERT_NE(v.data(), nullptr);
- EXPECT_EQ(v.data()[1], 20);
-}
-
-TEST(LlvmLibcVectorTest, RangeBasedForLoop) {
- vector<int> v;
- for (int i = 0; i < 5; ++i)
- ASSERT_TRUE(v.push_back(i * 10));
-
- int expected = 0;
- for (int val : v) {
- EXPECT_EQ(val, expected);
- expected += 10;
- }
- EXPECT_EQ(expected, 50);
-
- // Test cbegin / cend
- int const_expected = 0;
- for (auto it = v.cbegin(); it != v.cend(); ++it) {
- EXPECT_EQ(*it, const_expected);
- const_expected += 10;
- }
- EXPECT_EQ(const_expected, 50);
-}
-
-TEST(LlvmLibcVectorTest, MemberTypesAndMaxSize) {
- static_assert(LIBC_NAMESPACE::cpp::is_same_v<vector<int>::value_type, int>);
- static_assert(LIBC_NAMESPACE::cpp::is_same_v<vector<int>::size_type, size_t>);
- static_assert(
- LIBC_NAMESPACE::cpp::is_same_v<vector<int>::difference_type, ptrdiff_t>);
- static_assert(LIBC_NAMESPACE::cpp::is_same_v<vector<int>::pointer, int *>);
- static_assert(
- LIBC_NAMESPACE::cpp::is_same_v<vector<int>::const_pointer, const int *>);
-
- vector<int> v;
- EXPECT_GT(v.max_size(), size_t(0));
- EXPECT_EQ(v.max_size(), static_cast<size_t>(-1) / sizeof(int));
-}
-
-TEST(LlvmLibcVectorTest, PopBack) {
- vector<int> v;
- ASSERT_TRUE(v.push_back(1));
- ASSERT_TRUE(v.push_back(2));
- EXPECT_EQ(v.size(), size_t(2));
-
- v.pop_back();
- EXPECT_EQ(v.size(), size_t(1));
- EXPECT_EQ(v.back(), 1);
-
- v.pop_back();
- EXPECT_TRUE(v.empty());
- EXPECT_EQ(v.size(), size_t(0));
-}
-
-TEST(LlvmLibcVectorTest, ReserveAndShrinkToFit) {
- vector<int> v;
- ASSERT_TRUE(v.reserve(100));
- EXPECT_GE(v.capacity(), size_t(100));
- EXPECT_EQ(v.size(), size_t(0));
-
- ASSERT_TRUE(v.push_back(42));
- EXPECT_EQ(v.size(), size_t(1));
- EXPECT_GE(v.capacity(), size_t(100));
-
- v.shrink_to_fit();
- EXPECT_EQ(v.size(), size_t(1));
- EXPECT_EQ(v.capacity(), size_t(1));
- EXPECT_EQ(v[0], 42);
-}
-
-TEST(LlvmLibcVectorTest, ClearAndReset) {
- vector<int> v;
- for (int i = 0; i < 10; ++i)
- ASSERT_TRUE(v.push_back(i));
-
- size_t old_cap = v.capacity();
- v.clear();
- EXPECT_TRUE(v.empty());
- EXPECT_EQ(v.size(), size_t(0));
- EXPECT_EQ(v.capacity(), old_cap);
-
- // Can reuse buffer after clear
- ASSERT_TRUE(v.push_back(99));
- EXPECT_EQ(v.size(), size_t(1));
- EXPECT_EQ(v[0], 99);
-
- // Reset frees buffer
- v.reset();
- EXPECT_TRUE(v.empty());
- EXPECT_EQ(v.size(), size_t(0));
- EXPECT_EQ(v.capacity(), size_t(0));
- EXPECT_EQ(v.data(), static_cast<int *>(nullptr));
-}
-
-TEST(LlvmLibcVectorTest, Resize) {
- vector<int> v;
- ASSERT_TRUE(v.resize(5, 7));
- EXPECT_EQ(v.size(), size_t(5));
- for (size_t i = 0; i < 5; ++i)
- EXPECT_EQ(v[i], 7);
-
- ASSERT_TRUE(v.resize(2));
- EXPECT_EQ(v.size(), size_t(2));
- EXPECT_EQ(v[0], 7);
- EXPECT_EQ(v[1], 7);
-
- ASSERT_TRUE(v.resize(4, 9));
- EXPECT_EQ(v.size(), size_t(4));
- EXPECT_EQ(v[0], 7);
- EXPECT_EQ(v[1], 7);
- EXPECT_EQ(v[2], 9);
- EXPECT_EQ(v[3], 9);
-}
-
-TEST(LlvmLibcVectorTest, MoveOperations) {
- vector<int> v1;
- ASSERT_TRUE(v1.push_back(100));
- ASSERT_TRUE(v1.push_back(200));
-
- // Move constructor
- vector<int> v2(LIBC_NAMESPACE::cpp::move(v1));
- EXPECT_EQ(v2.size(), size_t(2));
- EXPECT_EQ(v2[0], 100);
- EXPECT_EQ(v2[1], 200);
- EXPECT_TRUE(v1.empty());
- EXPECT_EQ(v1.data(), static_cast<int *>(nullptr));
-
- // Move assignment
- vector<int> v3;
- v3 = LIBC_NAMESPACE::cpp::move(v2);
- EXPECT_EQ(v3.size(), size_t(2));
- EXPECT_EQ(v3[0], 100);
- EXPECT_EQ(v3[1], 200);
- EXPECT_TRUE(v2.empty());
- EXPECT_EQ(v2.data(), static_cast<int *>(nullptr));
-}
-
-TEST(LlvmLibcVectorTest, SwapOperations) {
- vector<int> a;
- ASSERT_TRUE(a.push_back(1));
- ASSERT_TRUE(a.push_back(2));
-
- vector<int> b;
- ASSERT_TRUE(b.push_back(30));
- ASSERT_TRUE(b.push_back(40));
- ASSERT_TRUE(b.push_back(50));
-
- // Member swap
- a.swap(b);
- EXPECT_EQ(a.size(), size_t(3));
- EXPECT_EQ(a[0], 30);
- EXPECT_EQ(a[1], 40);
- EXPECT_EQ(a[2], 50);
- EXPECT_EQ(b.size(), size_t(2));
- EXPECT_EQ(b[0], 1);
- EXPECT_EQ(b[1], 2);
-
- // Free swap
- LIBC_NAMESPACE::cpp::swap(a, b);
- EXPECT_EQ(a.size(), size_t(2));
- EXPECT_EQ(a[0], 1);
- EXPECT_EQ(a[1], 2);
- EXPECT_EQ(b.size(), size_t(3));
- EXPECT_EQ(b[0], 30);
- EXPECT_EQ(b[1], 40);
- EXPECT_EQ(b[2], 50);
-}
-
-struct LifetimeTracker {
- static int constructed;
- static int destructed;
- static int destroy_log[64];
- static int destroy_log_len;
- int value = 0;
- bool moved_from = false;
-
- LifetimeTracker() : value(0) { ++constructed; }
- explicit LifetimeTracker(int val) : value(val) { ++constructed; }
- LifetimeTracker(const LifetimeTracker &other) : value(other.value) {
- ++constructed;
- }
- LifetimeTracker(LifetimeTracker &&other) noexcept : value(other.value) {
- other.moved_from = true;
- ++constructed;
- }
- ~LifetimeTracker() {
- ++destructed;
- if (!moved_from && destroy_log_len < 64)
- destroy_log[destroy_log_len++] = value;
- }
-};
-
-int LifetimeTracker::constructed = 0;
-int LifetimeTracker::destructed = 0;
-int LifetimeTracker::destroy_log[64] = {};
-int LifetimeTracker::destroy_log_len = 0;
-
-TEST(LlvmLibcVectorTest, NonTrivialGrowthAndDestructionOrder) {
- LifetimeTracker::constructed = 0;
- LifetimeTracker::destructed = 0;
- LifetimeTracker::destroy_log_len = 0;
-
- {
- vector<LifetimeTracker> v;
- // Insert 20 elements to force reallocation past DEFAULT_INITIAL_CAPACITY
- // (16)
- for (int i = 0; i < 20; ++i)
- ASSERT_TRUE(v.emplace_back(i));
-
- EXPECT_EQ(v.size(), size_t(20));
- EXPECT_GE(v.capacity(), size_t(20));
- for (size_t i = 0; i < 20; ++i)
- EXPECT_EQ(v[i].value, int(i));
-
- v.shrink_to_fit();
- EXPECT_EQ(v.capacity(), size_t(20));
- for (size_t i = 0; i < 20; ++i)
- EXPECT_EQ(v[i].value, int(i));
-
- v.pop_back();
- EXPECT_EQ(v.size(), size_t(19));
- }
-
- EXPECT_EQ(LifetimeTracker::constructed, LifetimeTracker::destructed);
- // First destroyed was element 19 (via pop_back), then 18 down to 0 (LIFO)
- ASSERT_EQ(LifetimeTracker::destroy_log_len, 20);
- EXPECT_EQ(LifetimeTracker::destroy_log[0], 19);
- for (int i = 1; i < 20; ++i)
- EXPECT_EQ(LifetimeTracker::destroy_log[i], 19 - i);
-}
-
-TEST(LlvmLibcVectorTest, SelfReferentialPushBackAndResize) {
- vector<int> v;
- // Fill up to initial capacity (16) so the next push_back reallocates.
- for (int i = 0; i < 16; ++i)
- ASSERT_TRUE(v.push_back(i + 100));
-
- EXPECT_EQ(v.size(), v.capacity());
- // Self-referential push_back across reallocation boundary
- ASSERT_TRUE(v.push_back(v[0]));
- EXPECT_EQ(v.size(), size_t(17));
- EXPECT_EQ(v.back(), 100);
-
- // Self-referential resize across reallocation boundary
- ASSERT_TRUE(v.resize(40, v[1]));
- EXPECT_EQ(v.size(), size_t(40));
- EXPECT_EQ(v[39], 101);
-}
-
-TEST(LlvmLibcVectorTest, StringPointerVector) {
- vector<const char *> ptrs;
- ASSERT_TRUE(ptrs.push_back("first"));
- ASSERT_TRUE(ptrs.push_back("second"));
- ASSERT_TRUE(ptrs.push_back(nullptr));
-
- EXPECT_EQ(ptrs.size(), size_t(3));
- EXPECT_STREQ(ptrs[0], "first");
- EXPECT_STREQ(ptrs[1], "second");
- EXPECT_EQ(ptrs[2], nullptr);
- EXPECT_EQ(ptrs.data()[2], nullptr);
-}
``````````
</details>
https://github.com/llvm/llvm-project/pull/224976
More information about the libc-commits
mailing list