Skip to content

Commit

Permalink
[libc++][memory] Implements LWG3307. (llvm#99776)
Browse files Browse the repository at this point in the history
As a drive-by added a nodiscard test for allocate_at_least.

Implements
- LWG33307 std::allocator<void>().allocate(n)
  • Loading branch information
mordante authored Jul 23, 2024
1 parent 6cea818 commit e6388fe
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 1 deletion.
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx20Issues.csv
Original file line number Diff line number Diff line change
Expand Up @@ -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|"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/__memory/allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'}}
}
}
Original file line number Diff line number Diff line change
@@ -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'}}
}
}

0 comments on commit e6388fe

Please sign in to comment.