diff --git a/libcxx/docs/Status/Cxx20Issues.csv b/libcxx/docs/Status/Cxx20Issues.csv --- a/libcxx/docs/Status/Cxx20Issues.csv +++ b/libcxx/docs/Status/Cxx20Issues.csv @@ -108,7 +108,7 @@ "`3025 `__","Map-like container deduction guides should use ``pair``\ , not ``pair``\ ","San Diego","|Complete|","" "`3031 `__","Algorithms and predicates with non-const reference arguments","San Diego","","" "`3037 `__","``polymorphic_allocator``\ and incomplete types","San Diego","","" -"`3038 `__","``polymorphic_allocator::allocate``\ should not allow integer overflow to create vulnerabilities","San Diego","","" +"`3038 `__","``polymorphic_allocator::allocate``\ should not allow integer overflow to create vulnerabilities","San Diego","|Complete|","" "`3054 `__","``uninitialized_copy``\ appears to not be able to meet its exception-safety guarantee","San Diego","","" "`3065 `__","LWG 2989 missed that all ``path``\ 's other operators should be hidden friends as well","San Diego","|Complete|","" "`3096 `__","``path::lexically_relative``\ is confused by trailing slashes","San Diego","|Complete|","" @@ -162,7 +162,7 @@ "","","","","" "`3231 `__","``year_month_day_last::day``\ specification does not cover ``!ok()``\ values","Belfast","|Nothing To Do|","" "`3225 `__","``zoned_time``\ converting constructor shall not be ``noexcept``\ ","Belfast","","" -"`3190 `__","``std::allocator::allocate``\ sometimes returns too little storage","Belfast","","" +"`3190 `__","``std::allocator::allocate``\ sometimes returns too little storage","Belfast","|Complete|","" "`3218 `__","Modifier for ``%d``\ parse flag does not match POSIX and ``format``\ specification","Belfast","","" "`3224 `__","``zoned_time``\ constructor from ``TimeZonePtr``\ does not specify initialization of ``tp_``\ ","Belfast","","" "`3230 `__","Format specifier ``%y/%Y``\ is missing locale alternative versions","Belfast","","" @@ -200,7 +200,7 @@ "`3201 `__","``lerp``\ should be marked as ``noexcept``\ ","Prague","|Complete|","" "`3226 `__","``zoned_time``\ constructor from ``string_view``\ should accept ``zoned_time``\ ","Prague","","" "`3233 `__","Broken requirements for ``shared_ptr``\ converting constructors","Prague","","" -"`3237 `__","LWG 3038 and 3190 have inconsistent PRs","Prague","","" +"`3237 `__","LWG 3038 and 3190 have inconsistent PRs","Prague","|Complete|","14.0" "`3238 `__","Insufficiently-defined behavior of ``std::function``\ deduction guides","Prague","","" "`3242 `__","``std::format``\ : missing rules for ``arg-id``\ in ``width``\ and ``precision``\ ","Prague","|Complete|","Clang 14" "`3243 `__","``std::format``\ and negative zeroes","Prague","","" diff --git a/libcxx/include/__memory/allocator.h b/libcxx/include/__memory/allocator.h --- a/libcxx/include/__memory/allocator.h +++ b/libcxx/include/__memory/allocator.h @@ -98,8 +98,7 @@ _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp* allocate(size_t __n) { if (__n > allocator_traits::max_size(*this)) - __throw_length_error("allocator::allocate(size_t n)" - " 'n' exceeds maximum supported size"); + __libcpp_throw_bad_array_new_length(); if (__libcpp_is_constant_evaluated()) { return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); } else { @@ -181,8 +180,7 @@ _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const _Tp* allocate(size_t __n) { if (__n > allocator_traits::max_size(*this)) - __throw_length_error("allocator::allocate(size_t n)" - " 'n' exceeds maximum supported size"); + __libcpp_throw_bad_array_new_length(); if (__libcpp_is_constant_evaluated()) { return static_cast(::operator new(__n * sizeof(_Tp))); } else { diff --git a/libcxx/include/experimental/memory_resource b/libcxx/include/experimental/memory_resource --- a/libcxx/include/experimental/memory_resource +++ b/libcxx/include/experimental/memory_resource @@ -183,11 +183,8 @@ // 8.6.3, memory.polymorphic.allocator.mem _LIBCPP_INLINE_VISIBILITY _ValueType* allocate(size_t __n) { - if (__n > __max_size()) { - __throw_length_error( - "std::experimental::pmr::polymorphic_allocator::allocate(size_t n)" - " 'n' exceeds maximum supported size"); - } + if (__n > __max_size()) + __libcpp_throw_bad_array_new_length(); return static_cast<_ValueType*>( __res_->allocate(__n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType)) ); @@ -384,11 +381,8 @@ private: virtual void * do_allocate(size_t __bytes, size_t) { - if (__bytes > __max_size()) { - __throw_length_error( - "std::experimental::pmr::resource_adaptor::do_allocate(size_t bytes, size_t align)" - " 'bytes' exceeds maximum supported size"); - } + if (__bytes > __max_size()) + __libcpp_throw_bad_array_new_length(); size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign; return __alloc_.allocate(__s); } diff --git a/libcxx/include/new b/libcxx/include/new --- a/libcxx/include/new +++ b/libcxx/include/new @@ -148,6 +148,7 @@ #endif // !_LIBCPP_ABI_VCRUNTIME _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec +_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __libcpp_throw_bad_array_new_length(); #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) && \ !defined(_LIBCPP_ABI_VCRUNTIME) diff --git a/libcxx/src/new.cpp b/libcxx/src/new.cpp --- a/libcxx/src/new.cpp +++ b/libcxx/src/new.cpp @@ -47,6 +47,16 @@ #endif // !LIBSTDCXX +void +__libcpp_throw_bad_array_new_length() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_array_new_length(); +#else + _VSTD::abort(); +#endif +} + } // std #if !defined(__GLIBCXX__) && \ diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp --- a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp @@ -65,7 +65,7 @@ try { a.allocate(sizeTypeMax); assert(false); - } catch (std::exception const&) { + } catch (std::bad_array_new_length const&) { } // Test that allocating even one more than the max size does throw. @@ -73,7 +73,7 @@ try { a.allocate(overSize); assert(false); - } catch (std::exception const&) { + } catch (std::bad_array_new_length const&) { } } } diff --git a/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp --- a/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp +++ b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp @@ -99,7 +99,7 @@ try { m1.allocate(size); assert(false); - } catch (std::exception const&) { + } catch (std::bad_array_new_length const&) { } } #endif diff --git a/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp b/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp --- a/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp +++ b/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp @@ -24,7 +24,7 @@ try { TEST_IGNORE_NODISCARD a.allocate(count); assert(false); - } catch (const std::exception &) { + } catch (const std::bad_array_new_length &) { } }