Skip to content

release/23.x: [libc++] Don't require complete types in vector<T>::empty() (#210754) - #211026

Merged
dyung merged 1 commit into
llvm:release/23.xfrom
llvmbot:issue210754
Jul 22, 2026
Merged

release/23.x: [libc++] Don't require complete types in vector<T>::empty() (#210754)#211026
dyung merged 1 commit into
llvm:release/23.xfrom
llvmbot:issue210754

Conversation

@llvmbot

@llvmbot llvmbot commented Jul 21, 2026

Copy link
Copy Markdown
Member

Backport 17ac8fd

Requested by: @ldionne

@llvmbot
llvmbot requested a review from a team as a code owner July 21, 2026 15:54
@llvmbot llvmbot added this to the LLVM 23.x Release milestone Jul 21, 2026
@github-project-automation github-project-automation Bot moved this to Needs Triage in LLVM Release Status Jul 21, 2026
@llvmbot

llvmbot commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

@philnik777 What do you think about merging this PR to the release branch?

@llvmbot
llvmbot requested a review from philnik777 July 21, 2026 15:55
@llvmorg-github-actions llvmorg-github-actions Bot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jul 21, 2026
@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-libcxx

Author: llvmbot

Changes

Backport 17ac8fd

Requested by: @ldionne


Full diff: https://github.com/llvm/llvm-project/pull/211026.diff

3 Files Affected:

  • (modified) libcxx/include/__vector/layout.h (+11)
  • (modified) libcxx/include/__vector/vector.h (+1-1)
  • (added) libcxx/test/libcxx/containers/sequences/vector/incomplete_type.compile.pass.cpp (+27)
diff --git a/libcxx/include/__vector/layout.h b/libcxx/include/__vector/layout.h
index 3318a13a8ede1..af03556dc2636 100644
--- a/libcxx/include/__vector/layout.h
+++ b/libcxx/include/__vector/layout.h
@@ -199,6 +199,7 @@ class __vector_layout {
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __size() const _NOEXCEPT;
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __capacity() const _NOEXCEPT;
+  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __empty() const _NOEXCEPT;
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __end_ptr() _NOEXCEPT;
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_pointer __end_ptr() const _NOEXCEPT;
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __capacity_ptr() _NOEXCEPT;
@@ -313,6 +314,11 @@ __vector_layout<_Tp, _Alloc>::__capacity() const _NOEXCEPT {
   return __capacity_;
 }
 
+template <class _Tp, class _Alloc>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 bool __vector_layout<_Tp, _Alloc>::__empty() const _NOEXCEPT {
+  return __size_ == 0;
+}
+
 template <class _Tp, class _Alloc>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __vector_layout<_Tp, _Alloc>::pointer
 __vector_layout<_Tp, _Alloc>::__end_ptr() _NOEXCEPT {
@@ -425,6 +431,11 @@ __vector_layout<_Tp, _Alloc>::__capacity() const _NOEXCEPT {
   return static_cast<size_type>(__capacity_ - __begin_);
 }
 
+template <class _Tp, class _Alloc>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 bool __vector_layout<_Tp, _Alloc>::__empty() const _NOEXCEPT {
+  return __begin_ == __end_;
+}
+
 template <class _Tp, class _Alloc>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __vector_layout<_Tp, _Alloc>::pointer
 __vector_layout<_Tp, _Alloc>::__end_ptr() _NOEXCEPT {
diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index 8226a7f87a119..5e9fa4a7d0030 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -398,7 +398,7 @@ class vector {
     return __layout_.__capacity();
   }
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
-    return size() == 0;
+    return __layout_.__empty();
   }
 
   [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
diff --git a/libcxx/test/libcxx/containers/sequences/vector/incomplete_type.compile.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/incomplete_type.compile.pass.cpp
new file mode 100644
index 0000000000000..029d29eb437f8
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/vector/incomplete_type.compile.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// This test pins down the current libc++ behavior that vector<T>::empty() can be
+// called even when T is an incomplete type. The standard does not require this:
+// [vector.overview] only guarantees that an incomplete type may be used to
+// instantiate vector, and requires the type to be complete before any method is
+// called.
+//
+// However, libc++ made that work previously, and this test pins down that behavior
+// to avoid breaking it unintentionally. Note that this is not a guarantee to users
+// that we will support this in the future: this merely guards against changing this
+// behavior unknowingly.
+
+#include <vector>
+
+struct Incomplete;
+
+bool call_empty(std::vector<Incomplete>& v) { return v.empty(); }
+bool call_empty_const(const std::vector<Incomplete>& v) { return v.empty(); }

@dyung dyung moved this from Needs Triage to Needs Review in LLVM Release Status Jul 21, 2026
@github-project-automation github-project-automation Bot moved this from Needs Review to Needs Merge in LLVM Release Status Jul 22, 2026
)

This was previously not required, but the patch to introduce a new
size-based vector layout unintentionally added this new requirement. We
almost certainly not want to promise this guarantee going forward, but
we should actually land this change explicitly and consider the
transition story, not do it as a fallout of another refactoring.

Fixes llvm#210732

(cherry picked from commit 17ac8fd)
@dyung
dyung merged commit 165c472 into llvm:release/23.x Jul 22, 2026
2 of 4 checks passed
@github-project-automation github-project-automation Bot moved this from Needs Merge to Done in LLVM Release Status Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Projects

Development

Successfully merging this pull request may close these issues.

4 participants