[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:19:12 PDT 2024
https://github.com/mordante updated https://github.com/llvm/llvm-project/pull/99776
>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 1/2] [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'}}
+ }
+}
>From 899cc0327d1088c12f75b774f0d0455d04c5983e Mon Sep 17 00:00:00 2001
From: Mark de Wever <koraq at xs4all.nl>
Date: Sat, 20 Jul 2024 21:08:46 +0200
Subject: [PATCH 2/2] [libc++][syncbuf] Implements LWG3253.
Note the tests already tested this behaviour and the wording change is NFC.
Implements
- LWG3253 basic_syncbuf::basic_syncbuf() should not be explicit
---
libcxx/docs/Status/Cxx20Issues.csv | 2 +-
libcxx/include/syncstream | 9 +++++++--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/libcxx/docs/Status/Cxx20Issues.csv b/libcxx/docs/Status/Cxx20Issues.csv
index 4f8118b5a35fb..85a8ee2190307 100644
--- a/libcxx/docs/Status/Cxx20Issues.csv
+++ b/libcxx/docs/Status/Cxx20Issues.csv
@@ -172,7 +172,7 @@
"`3221 <https://wg21.link/LWG3221>`__","Result of ``year_month``\ arithmetic with ``months``\ is ambiguous","Belfast","|Complete|","8.0"
"`3235 <https://wg21.link/LWG3235>`__","``parse``\ manipulator without abbreviation is not callable","Belfast","",""
"`3246 <https://wg21.link/LWG3246>`__","What are the constraints on the template parameter of ``basic_format_arg``\ ?","Belfast","","","|format|"
-"`3253 <https://wg21.link/LWG3253>`__","``basic_syncbuf::basic_syncbuf()``\ should not be explicit","Belfast","",""
+"`3253 <https://wg21.link/LWG3253>`__","``basic_syncbuf::basic_syncbuf()``\ should not be explicit","Belfast","|Complete|","20.0"
"`3245 <https://wg21.link/LWG3245>`__","Unnecessary restriction on ``'%p'``\ parse specifier","Belfast","","","|chrono|"
"`3244 <https://wg21.link/LWG3244>`__","Constraints for ``Source``\ in |sect|\ [fs.path.req] insufficiently constrainty","Belfast","",""
"`3241 <https://wg21.link/LWG3241>`__","``chrono-spec``\ grammar ambiguity in |sect|\ [time.format]","Belfast","|Complete|","16.0","|chrono| |format|"
diff --git a/libcxx/include/syncstream b/libcxx/include/syncstream
index e6f35b6f428ed..a0617f4acf5b6 100644
--- a/libcxx/include/syncstream
+++ b/libcxx/include/syncstream
@@ -46,7 +46,9 @@ namespace std {
using streambuf_type = basic_streambuf<charT, traits>;
// [syncstream.syncbuf.cons], construction and destruction
- explicit basic_syncbuf(streambuf_type* obuf = nullptr)
+ basic_syncbuf()
+ : basic_syncbuf(nullptr) {}
+ explicit basic_syncbuf(streambuf_type* obuf)
: basic_syncbuf(obuf, Allocator()) {}
basic_syncbuf(streambuf_type*, const Allocator&);
basic_syncbuf(basic_syncbuf&&);
@@ -253,7 +255,10 @@ public:
// [syncstream.syncbuf.cons], construction and destruction
- _LIBCPP_HIDE_FROM_ABI explicit basic_syncbuf(streambuf_type* __obuf = nullptr)
+ _LIBCPP_HIDE_FROM_ABI basic_syncbuf()
+ : basic_syncbuf(nullptr) {}
+
+ _LIBCPP_HIDE_FROM_ABI explicit basic_syncbuf(streambuf_type* __obuf)
: basic_syncbuf(__obuf, _Allocator()) {}
_LIBCPP_HIDE_FROM_ABI basic_syncbuf(streambuf_type* __obuf, _Allocator const& __alloc)
More information about the libcxx-commits
mailing list