https://github.com/llvmbot created 
https://github.com/llvm/llvm-project/pull/211026

Backport 17ac8fdd95283110a14f1de8c15a0fc661119296

Requested by: @ldionne

>From 72e6e7b9af93c67dfe16d15784aa607bb905edd0 Mon Sep 17 00:00:00 2001
From: Louis Dionne <[email protected]>
Date: Tue, 21 Jul 2026 10:21:27 -0400
Subject: [PATCH] [libc++] Don't require complete types in vector<T>::empty()
 (#210754)

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 #210732

(cherry picked from commit 17ac8fdd95283110a14f1de8c15a0fc661119296)
---
 libcxx/include/__vector/layout.h              | 11 ++++++++
 libcxx/include/__vector/vector.h              |  2 +-
 .../vector/incomplete_type.compile.pass.cpp   | 27 +++++++++++++++++++
 3 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 
libcxx/test/libcxx/containers/sequences/vector/incomplete_type.compile.pass.cpp

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(); }

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to