From 9bc2dd1a7015b58c9c68e8174e5d2756d955c0ca Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 31 Jul 2026 13:21:58 -0400 Subject: [PATCH] [libc++] Add an assertion for monotonic_buffer_resource's initial_size (#213136) [mem.res.monotonic.buffer.ctor] requires initial_size to be greater than zero for the two constructors that take one, but we silently accepted zero. Add a hardening assertion for that precondition. Fixes #213059 --- .../monotonic_buffer_resource.h | 11 +++++- .../assert.initial_size.pass.cpp | 38 +++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 libcxx/test/libcxx/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/assert.initial_size.pass.cpp diff --git a/libcxx/include/__memory_resource/monotonic_buffer_resource.h b/libcxx/include/__memory_resource/monotonic_buffer_resource.h index a6d292386169..2a0361165ddc 100644 --- a/libcxx/include/__memory_resource/monotonic_buffer_resource.h +++ b/libcxx/include/__memory_resource/monotonic_buffer_resource.h @@ -9,6 +9,7 @@ #ifndef _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H #define _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H +#include <__assert> #include <__config> #include <__cstddef/size_t.h> #include <__memory/addressof.h> @@ -54,7 +55,10 @@ public: : monotonic_buffer_resource(nullptr, __default_buffer_capacity, get_default_resource()) {} _LIBCPP_HIDE_FROM_ABI explicit monotonic_buffer_resource(size_t __initial_size) - : monotonic_buffer_resource(nullptr, __initial_size, get_default_resource()) {} + : monotonic_buffer_resource(nullptr, __initial_size, get_default_resource()) { + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + __initial_size > 0, "monotonic_buffer_resource: initial_size must be greater than zero"); + } _LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource(void* __buffer, size_t __buffer_size) : monotonic_buffer_resource(__buffer, __buffer_size, get_default_resource()) {} @@ -63,7 +67,10 @@ public: : monotonic_buffer_resource(nullptr, __default_buffer_capacity, __upstream) {} _LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource(size_t __initial_size, memory_resource* __upstream) - : monotonic_buffer_resource(nullptr, __initial_size, __upstream) {} + : monotonic_buffer_resource(nullptr, __initial_size, __upstream) { + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + __initial_size > 0, "monotonic_buffer_resource: initial_size must be greater than zero"); + } _LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource(void* __buffer, size_t __buffer_size, memory_resource* __upstream) : __res_(__upstream) { diff --git a/libcxx/test/libcxx/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/assert.initial_size.pass.cpp b/libcxx/test/libcxx/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/assert.initial_size.pass.cpp new file mode 100644 index 000000000000..61c331d9158c --- /dev/null +++ b/libcxx/test/libcxx/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.ctor/assert.initial_size.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// class monotonic_buffer_resource + +// explicit monotonic_buffer_resource(size_t initial_size); +// monotonic_buffer_resource(size_t initial_size, memory_resource* upstream); + +// [mem.res.monotonic.buffer.ctor] requires initial_size to be greater than zero. +// Make sure that passing zero triggers an assertion. + +// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: availability-pmr-missing +// REQUIRES: has-unix-headers +// REQUIRES: libcpp-hardening-mode={{extensive|debug}} +// UNSUPPORTED: libcpp-assertion-semantic={{ignore|observe}} +// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing + +#include +#include + +#include "check_assertion.h" + +int main(int, char**) { + TEST_LIBCPP_ASSERT_FAILURE(std::pmr::monotonic_buffer_resource(std::size_t(0)), + "monotonic_buffer_resource: initial_size must be greater than zero"); + TEST_LIBCPP_ASSERT_FAILURE(std::pmr::monotonic_buffer_resource(std::size_t(0), std::pmr::new_delete_resource()), + "monotonic_buffer_resource: initial_size must be greater than zero"); + + return 0; +}