[libcxx-commits] [libcxx] [libc++][memory] Implements LWG3307. (PR #99776)
Mark de Wever via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Jul 20 12:18:30 PDT 2024
https://github.com/mordante created https://github.com/llvm/llvm-project/pull/99776
As a drive-by added a nodiscard test for allocate_at_least.
Implements
- LWG33307 std::allocator<void>().allocate(n)
>From 425cdff68fe1e377034cba0b2a21ca4d1ba76624 Mon Sep 17 00:00:00 2001
From: Mark de Wever <koraq at xs4all.nl>
Date: Sat, 20 Jul 2024 21:08:48 +0200
Subject: [PATCH] [libc++][memory] Implements LWG3307.
As a drive-by added a nodiscard test for allocate_at_least.
Implements
- LWG33307 std::allocator<void>().allocate(n)
---
libcxx/docs/Status/Cxx20Issues.csv | 2 +-
libcxx/include/__memory/allocator.h | 2 ++
.../allocator.members/allocate.verify.cpp | 14 ++++++++
.../allocate_at_least.verify.cpp | 35 +++++++++++++++++++
4 files changed, 52 insertions(+), 1 deletion(-)
create mode 100644 libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate_at_least.verify.cpp
diff --git a/libcxx/docs/Status/Cxx20Issues.csv b/libcxx/docs/Status/Cxx20Issues.csv
index 1a40a4472a405..4f8118b5a35fb 100644
--- a/libcxx/docs/Status/Cxx20Issues.csv
+++ b/libcxx/docs/Status/Cxx20Issues.csv
@@ -233,7 +233,7 @@
"`3302 <https://wg21.link/LWG3302>`__","Range adaptor objects ``keys``\ and ``values``\ are unspecified","Prague","|Complete|","16.0","|ranges|"
"`3303 <https://wg21.link/LWG3303>`__","Bad ""``constexpr``\ "" marker for ``destroy/destroy_n``\ ","Prague","",""
"`3304 <https://wg21.link/LWG3304>`__","Allocate functions of ``std::polymorphic_allocator``\ should require ``[[nodiscard]]``\ ","Prague","|Complete|","16.0"
-"`3307 <https://wg21.link/LWG3307>`__","``std::allocator<void>().allocate(n)``\ ","Prague","",""
+"`3307 <https://wg21.link/LWG3307>`__","``std::allocator<void>().allocate(n)``\ ","Prague","|Complete|","20.0"
"`3310 <https://wg21.link/LWG3310>`__","Replace ``SIZE_MAX``\ with ``numeric_limits<size_t>::max()``\ ","Prague","|Complete|","16.0"
"`3313 <https://wg21.link/LWG3313>`__","``join_view::iterator::operator--``\ is incorrectly constrained","Prague","|Complete|","14.0","|ranges|"
"`3314 <https://wg21.link/LWG3314>`__","Is stream insertion behavior locale dependent when ``Period::type``\ is ``micro``\ ?","Prague","|Complete|","16.0","|chrono|"
diff --git a/libcxx/include/__memory/allocator.h b/libcxx/include/__memory/allocator.h
index 2d8624e771bce..ae1f549626ee4 100644
--- a/libcxx/include/__memory/allocator.h
+++ b/libcxx/include/__memory/allocator.h
@@ -110,6 +110,7 @@ class _LIBCPP_TEMPLATE_VIS allocator : private __non_trivial_if<!is_void<_Tp>::v
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator(const allocator<_Up>&) _NOEXCEPT {}
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp* allocate(size_t __n) {
+ static_assert(sizeof(_Tp) >= 0, "cannot allocate memory for an incomplete type");
if (__n > allocator_traits<allocator>::max_size(*this))
__throw_bad_array_new_length();
if (__libcpp_is_constant_evaluated()) {
@@ -121,6 +122,7 @@ class _LIBCPP_TEMPLATE_VIS allocator : private __non_trivial_if<!is_void<_Tp>::v
#if _LIBCPP_STD_VER >= 23
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr allocation_result<_Tp*> allocate_at_least(size_t __n) {
+ static_assert(sizeof(_Tp) >= 0, "cannot allocate memory for an incomplete type");
return {allocate(__n), __n};
}
#endif
diff --git a/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.verify.cpp b/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.verify.cpp
index b2b6f51e98245..886ce7ac8d4a0 100644
--- a/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.verify.cpp
+++ b/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.verify.cpp
@@ -15,7 +15,21 @@
#include <memory>
+struct incomplete;
+
void f() {
+ {
std::allocator<int> a;
a.allocate(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ {
+ std::allocator<void> a;
+ [[maybe_unused]] auto b =
+ a.allocate(3); // expected-error@*:* {{invalid application of 'sizeof' to an incomplete type 'void'}}
+ }
+ {
+ std::allocator<incomplete> a;
+ [[maybe_unused]] auto b =
+ a.allocate(3); // expected-error@*:* {{invalid application of 'sizeof' to an incomplete type 'incomplete'}}
+ }
}
diff --git a/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate_at_least.verify.cpp b/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate_at_least.verify.cpp
new file mode 100644
index 0000000000000..cfee54198e099
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate_at_least.verify.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <memory>
+
+// allocator:
+// T* allocate_at_least(size_t n);
+
+#include <memory>
+
+struct incomplete;
+
+void f() {
+ {
+ std::allocator<int> a;
+ a.allocate_at_least(3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ {
+ std::allocator<void> a;
+ [[maybe_unused]] auto b =
+ a.allocate_at_least(3); // expected-error@*:* {{invalid application of 'sizeof' to an incomplete type 'void'}}
+ }
+ {
+ std::allocator<incomplete> a;
+ [[maybe_unused]] auto b = a.allocate_at_least(
+ 3); // expected-error@*:* {{invalid application of 'sizeof' to an incomplete type 'incomplete'}}
+ }
+}
More information about the libcxx-commits
mailing list