[libcxx-commits] [libcxx] [String] Allow fancy pointer as pointer type of basic_string allocator (PR #191023)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Apr 8 11:05:03 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Nikita Belenkiy (kitsnet)
<details>
<summary>Changes</summary>
Currently, basic_string does not support custom allocators which use fancy pointers that are not trivially constructible and destructible as the pointer type. This happens because in its internal representation, fancy pointers are stored in a union, which deletes the default constructor of such a union.
In order to allow fancy pointers, this PR does:
* add an explicit default constructor to the underlying union;
* add explicit __construct_at() to start lifetime of the fancy pointer in constant expressions.
Addresses bug report: https://bugs.llvm.org/show_bug.cgi?id=20508 Takes over: https://github.com/llvm/llvm-project/pull/71182 Originally https://reviews.llvm.org/D132149
---
Patch is 214.73 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/191023.diff
224 Files Affected:
- (modified) libcxx/include/string (+18-2)
- (modified) libcxx/test/libcxx/strings/basic.string/alignof.compile.pass.cpp (+15)
- (modified) libcxx/test/libcxx/strings/basic.string/sizeof.compile.pass.cpp (+35)
- (modified) libcxx/test/libcxx/strings/basic.string/string.access/assert.back.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.access/assert.cback.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.access/assert.cfront.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.access/assert.cindex.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.access/assert.front.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.access/assert.index.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.add.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.decrement.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.dereference.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.increment.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.index.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.iterators/debug.iterator.compare.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.iterators/debug.iterator.subtract.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.erase_iter.null.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.pop_back.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.erase.iter.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.erase.iter_iter.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_char.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_iter_iter.pass.cpp (+2)
- (modified) libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_size_char.pass.cpp (+2)
- (modified) libcxx/test/std/containers/from_range_helpers.h (+2)
- (modified) libcxx/test/std/containers/insert_range_helpers.h (+4)
- (modified) libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.access/at.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.access/back.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.access/front.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.access/index.pass.cpp (+3)
- (modified) libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.capacity/clear.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.capacity/empty.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.capacity/length.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.capacity/max_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.capacity/reserve.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.capacity/size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.cons/T_size_size.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.cons/alloc.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.cons/copy.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.cons/default.pass.cpp (+3)
- (modified) libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp (+3)
- (modified) libcxx/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp (+11)
- (modified) libcxx/test/std/strings/basic.string/string.cons/move.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp (+12)
- (modified) libcxx/test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp (+4)
- (modified) libcxx/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp (+4)
- (modified) libcxx/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.cons/string_view.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp (+10)
- (modified) libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp (+10)
- (modified) libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.cons/substr_rvalue.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.iterators/begin.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.iterators/cend.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.iterators/crend.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.iterators/end.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.iterators/rend.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_append/T_size_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_view.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_assign/T_size_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp (+2-2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp (+8)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_view.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_copy/copy.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp (+3-1)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_T_size_size.pass.cpp (+3)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp (+3)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_insert/string_view.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp (+3-1)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_T_size_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_view.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim_rv.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_rv.pass.cpp (+4)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_insert.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/pointer_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string_view.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_view_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/char_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/pointer_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_char.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/pointer_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string_view.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_view_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/pointer_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string_view.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_view_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/pointer_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string_view.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_view_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/pointer_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string_view.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_view_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/pointer_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string_view.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_view_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string.accessors/c_str.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string.accessors/data.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string.accessors/get_allocator.pass.cpp (+1)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_compare/pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_T_size_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_size_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_view.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_compare/string_view.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/char_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_view_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/char_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_view_size.pass.cpp (+2)
- (modified) libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/char_size.pass.cpp (+2)
``````````diff
diff --git a/libcxx/include/string b/libcxx/include/string
index 0c8767df2cdd2..afa57af704ce5 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -751,7 +751,7 @@ public:
using const_pointer = typename __alloc_traits::const_pointer;
// A basic_string contains the following members which may be trivially relocatable:
- // - pointer: is currently assumed to be trivially relocatable, but is still checked in case that changes
+ // - pointer: may or may not be trivially relocatable, so it's checked
// - size_type: is always trivially relocatable, since it has to be an integral type
// - value_type: is always trivially relocatable, since it has to be trivial
// - unsigned char: is a fundamental type, so it's trivially relocatable
@@ -894,7 +894,8 @@ private:
__short __s;
__long __l;
- __rep() = default;
+ // not using =default, as it would be deleted if __long is not trivially constructible
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep() : __s() {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__short __r) : __s(__r) {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__long __r) : __l(__r) {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__uninitialized_tag) {}
@@ -2116,6 +2117,20 @@ private:
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) { return __sz < __min_cap; }
+ // If __long is not trivially constructible (this occurs if the pointer type inside __long is not trivially constructible)
+ // then the lifetime of __l must be explicitly started with std::__construct_at before it can be assigned to. If __long is
+ // trivially constructible, then the lifetime of __l can be implicitly started with a simple assignment and therefore does
+ // not need to be explicitly initialised here.
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __begin_long_lifetime() {
+#if _LIBCPP_STD_VER >= 17
+ if constexpr(!__is_trivially_constructible(__long)) {
+#else
+ if (!__is_trivially_constructible(__long)) {
+#endif // _LIBCPP_STD_VER >= 17
+ std::__construct_at(std::addressof(__rep_.__l));
+ }
+ }
+
template <class _Iterator, class _Sentinel>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n);
@@ -2293,6 +2308,7 @@ private:
__annotate_new(__size);
return __get_short_pointer();
} else {
+ __begin_long_lifetime();
__rep_.__l = __allocate_long_buffer(__alloc_, __size);
__annotate_new(__size);
return __get_long_pointer();
diff --git a/libcxx/test/libcxx/strings/basic.string/alignof.compile.pass.cpp b/libcxx/test/libcxx/strings/basic.string/alignof.compile.pass.cpp
index 49cbde14c568b..f78a7ab35326b 100644
--- a/libcxx/test/libcxx/strings/basic.string/alignof.compile.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/alignof.compile.pass.cpp
@@ -54,6 +54,9 @@ class small_iter_allocator {
template <class CharT>
using min_string = std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>;
+template <class CharT>
+using fancy_string = std::basic_string<CharT, std::char_traits<CharT>, fancy_pointer_allocator<CharT>>;
+
template <class CharT>
using test_string = std::basic_string<CharT, std::char_traits<CharT>, test_allocator<CharT>>;
@@ -64,6 +67,7 @@ using small_string = std::basic_string<CharT, std::char_traits<CharT>, small_ite
static_assert(alignof(std::string) == 8, "");
static_assert(alignof(min_string<char>) == 8, "");
+static_assert(alignof(fancy_string<char>) == 8, "");
static_assert(alignof(test_string<char>) == 8, "");
static_assert(alignof(small_string<char>) == 2, "");
@@ -71,11 +75,13 @@ static_assert(alignof(small_string<char>) == 2, "");
# if __WCHAR_WIDTH__ == 32
static_assert(alignof(std::wstring) == 8, "");
static_assert(alignof(min_string<wchar_t>) == 8, "");
+static_assert(alignof(fancy_string<wchar_t>) == 8, "");
static_assert(alignof(test_string<wchar_t>) == 8, "");
static_assert(alignof(small_string<wchar_t>) == 4, "");
# elif __WCHAR_WIDTH__ == 16
static_assert(alignof(std::wstring) == 8, "");
static_assert(alignof(min_string<wchar_t>) == 8, "");
+static_assert(alignof(fancy_string<wchar_t>) == 8, "");
static_assert(alignof(test_string<wchar_t>) == 8, "");
static_assert(alignof(small_string<wchar_t>) == 2, "");
# else
@@ -86,6 +92,7 @@ static_assert(alignof(small_string<wchar_t>) == 2, "");
# ifndef TEST_HAS_NO_CHAR8_T
static_assert(alignof(std::u8string) == 8, "");
static_assert(alignof(min_string<char8_t>) == 8, "");
+static_assert(alignof(fancy_string<char8_t>) == 8, "");
static_assert(alignof(test_string<char8_t>) == 8, "");
static_assert(alignof(small_string<char8_t>) == 2, "");
# endif
@@ -95,6 +102,8 @@ static_assert(alignof(std::u16string) == 8, "");
static_assert(alignof(std::u32string) == 8, "");
static_assert(alignof(min_string<char16_t>) == 8, "");
static_assert(alignof(min_string<char32_t>) == 8, "");
+static_assert(alignof(fancy_string<char16_t>) == 8, "");
+static_assert(alignof(fancy_string<char32_t>) == 8, "");
static_assert(alignof(test_string<char16_t>) == 8, "");
static_assert(alignof(test_string<char32_t>) == 8, "");
static_assert(alignof(small_string<char16_t>) == 2, "");
@@ -105,6 +114,7 @@ static_assert(alignof(small_string<char32_t>) == 4, "");
static_assert(alignof(std::string) == 4, "");
static_assert(alignof(min_string<char>) == 4, "");
+static_assert(alignof(fancy_string<char>) == 4, "");
static_assert(alignof(test_string<char>) == 4, "");
static_assert(alignof(small_string<char>) == 2, "");
@@ -112,11 +122,13 @@ static_assert(alignof(small_string<char>) == 2, "");
# if __WCHAR_WIDTH__ == 32
static_assert(alignof(std::wstring) == 4, "");
static_assert(alignof(min_string<wchar_t>) == 4, "");
+static_assert(alignof(fancy_string<wchar_t>) == 4, "");
static_assert(alignof(test_string<wchar_t>) == 4, "");
static_assert(alignof(small_string<wchar_t>) == 4, "");
# elif __WCHAR_WIDTH__ == 16
static_assert(alignof(std::wstring) == 4, "");
static_assert(alignof(min_string<wchar_t>) == 4, "");
+static_assert(alignof(fancy_string<wchar_t>) == 4, "");
static_assert(alignof(test_string<wchar_t>) == 4, "");
static_assert(alignof(small_string<wchar_t>) == 2, "");
# else
@@ -127,6 +139,7 @@ static_assert(alignof(small_string<wchar_t>) == 2, "");
# ifndef TEST_HAS_NO_CHAR8_T
static_assert(alignof(std::u8string) == 4, "");
static_assert(alignof(min_string<char8_t>) == 4, "");
+static_assert(alignof(fancy_string<char8_t>) == 4, "");
static_assert(alignof(test_string<char8_t>) == 4, "");
static_assert(alignof(small_string<char8_t>) == 2, "");
# endif
@@ -136,6 +149,8 @@ static_assert(alignof(std::u16string) == 4, "");
static_assert(alignof(std::u32string) == 4, "");
static_assert(alignof(min_string<char16_t>) == 4, "");
static_assert(alignof(min_string<char32_t>) == 4, "");
+static_assert(alignof(fancy_string<char16_t>) == 4, "");
+static_assert(alignof(fancy_string<char32_t>) == 4, "");
static_assert(alignof(test_string<char16_t>) == 4, "");
static_assert(alignof(test_string<char32_t>) == 4, "");
static_assert(alignof(small_string<char32_t>) == 4, "");
diff --git a/libcxx/test/libcxx/strings/basic.string/sizeof.compile.pass.cpp b/libcxx/test/libcxx/strings/basic.string/sizeof.compile.pass.cpp
index 31f1a94c73216..73d0702d9f803 100644
--- a/libcxx/test/libcxx/strings/basic.string/sizeof.compile.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/sizeof.compile.pass.cpp
@@ -52,6 +52,9 @@ class small_iter_allocator {
template <class CharT>
using min_string = std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT> >;
+template <class CharT>
+using fancy_string = std::basic_string<CharT, std::char_traits<CharT>, fancy_pointer_allocator<CharT> >;
+
template <class CharT>
using test_string = std::basic_string<CharT, std::char_traits<CharT>, test_allocator<CharT> >;
@@ -62,6 +65,9 @@ using small_string = std::basic_string<CharT, std::char_traits<CharT>, small_ite
static_assert(sizeof(std::string) == 24, "");
static_assert(sizeof(min_string<char>) == 24, "");
+# if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<char>) == 24, "");
+# endif
static_assert(sizeof(test_string<char>) == 32, "");
static_assert(sizeof(small_string<char>) == 6, "");
@@ -69,11 +75,17 @@ static_assert(sizeof(small_string<char>) == 6, "");
# if __WCHAR_WIDTH__ == 32
static_assert(sizeof(std::wstring) == 24, "");
static_assert(sizeof(min_string<wchar_t>) == 24, "");
+# if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<wchar_t>) == 24, "");
+# endif
static_assert(sizeof(test_string<wchar_t>) == 32, "");
static_assert(sizeof(small_string<wchar_t>) == 12, "");
# elif __WCHAR_WIDTH__ == 16
static_assert(sizeof(std::wstring) == 24, "");
static_assert(sizeof(min_string<wchar_t>) == 24, "");
+# if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<wchar_t>) == 24, "");
+# endif
static_assert(sizeof(test_string<wchar_t>) == 32, "");
static_assert(sizeof(small_string<wchar_t>) == 6, "");
# else
@@ -84,6 +96,9 @@ static_assert(sizeof(small_string<wchar_t>) == 6, "");
# ifndef TEST_HAS_NO_CHAR8_T
static_assert(sizeof(std::u8string) == 24, "");
static_assert(sizeof(min_string<char8_t>) == 24, "");
+# if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<char8_t>) == 24, "");
+# endif
static_assert(sizeof(test_string<char8_t>) == 32, "");
static_assert(sizeof(small_string<char8_t>) == 6, "");
# endif
@@ -93,6 +108,10 @@ static_assert(sizeof(std::u16string) == 24, "");
static_assert(sizeof(std::u32string) == 24, "");
static_assert(sizeof(min_string<char16_t>) == 24, "");
static_assert(sizeof(min_string<char32_t>) == 24, "");
+# if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<char16_t>) == 24, "");
+static_assert(sizeof(fancy_string<char32_t>) == 24, "");
+# endif
static_assert(sizeof(test_string<char16_t>) == 32, "");
static_assert(sizeof(test_string<char32_t>) == 32, "");
static_assert(sizeof(small_string<char16_t>) == 6, "");
@@ -103,6 +122,9 @@ static_assert(sizeof(small_string<char32_t>) == 12, "");
static_assert(sizeof(std::string) == 12, "");
static_assert(sizeof(min_string<char>) == 12, "");
+# if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<char>) == 12, "");
+# endif
static_assert(sizeof(test_string<char>) == 24, "");
static_assert(sizeof(small_string<char>) == 6, "");
@@ -110,11 +132,17 @@ static_assert(sizeof(small_string<char>) == 6, "");
# if __WCHAR_WIDTH__ == 32
static_assert(sizeof(std::wstring) == 12, "");
static_assert(sizeof(min_string<wchar_t>) == 12, "");
+# if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<wchar_t>) == 12, "");
+# endif
static_assert(sizeof(test_string<wchar_t>) == 24, "");
static_assert(sizeof(small_string<wchar_t>) == 12, "");
# elif __WCHAR_WIDTH__ == 16
static_assert(sizeof(std::wstring) == 12, "");
static_assert(sizeof(min_string<wchar_t>) == 12, "");
+# if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<wchar_t>) == 12, "");
+# endif
static_assert(sizeof(test_string<wchar_t>) == 24, "");
static_assert(sizeof(small_string<wchar_t>) == 6, "");
# else
@@ -125,6 +153,9 @@ static_assert(sizeof(small_string<wchar_t>) == 6, "");
# ifndef TEST_HAS_NO_CHAR8_T
static_assert(sizeof(std::u8string) == 12, "");
static_assert(sizeof(min_string<char8_t>) == 12, "");
+# if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<char8_t>) == 12, "");
+# endif
static_assert(sizeof(test_string<char8_t>) == 24, "");
static_assert(sizeof(small_string<char>) == 6, "");
# endif
@@ -134,6 +165,10 @@ static_assert(sizeof(std::u16string) == 12, "");
static_assert(sizeof(std::u32string) == 12, "");
static_assert(sizeof(min_string<char16_t>) == 12, "");
static_assert(sizeof(min_string<char32_t>) == 12, "");
+# if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<char16_t>) == 12, "");
+static_assert(sizeof(fancy_string<char32_t>) == 12, "");
+# endif
static_assert(sizeof(test_string<char16_t>) == 24, "");
static_assert(sizeof(test_string<char32_t>) == 24, "");
static_assert(sizeof(small_string<char16_t>) == 6, "");
diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.back.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.back.pass.cpp
index 36a485a1e4d00..975414643b73b 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.back.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.back.pass.cpp
@@ -19,6 +19,7 @@
#include "check_assertion.h"
#include "min_allocator.h"
+#include "test_allocator.h"
template <class S>
void test() {
@@ -29,6 +30,7 @@ void test() {
int main(int, char**) {
test<std::string>();
test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+ test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
return 0;
}
diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cback.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cback.pass.cpp
index d810acd67e7e7..40496f3b7c57d 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cback.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cback.pass.cpp
@@ -19,6 +19,7 @@
#include "check_assertion.h"
#include "min_allocator.h"
+#include "test_allocator.h"
template <class S>
void test() {
@@ -29,6 +30,7 @@ void test() {
int main(int, char**) {
test<std::string>();
test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+ test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
return 0;
}
diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cfront.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cfront.pass.cpp
index 12e7ef3328b04..0fa0d2ffe29f5 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cfront.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cfront.pass.cpp
@@ -19,6 +19,7 @@
#include "check_assertion.h"
#include "min_allocator.h"
+#include "test_allocator.h"
template <class S>
void test() {
@@ -29,6 +30,7 @@ void test() {
int main(int, char**) {
test<std::string>();
test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+ test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
return 0;
}
diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cindex.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cindex.pass.cpp
index 3983352712963..a34ef54ac4804 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cindex.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cindex.pass.cpp
@@ -20,6 +20,7 @@
#include "check_assertion.h"
#include "min_allocator.h"
+#include "test_allocator.h"
template <class S>
void test() {
@@ -31,6 +32,7 @@ void test() {
int main(int, char**) {
test<std::string>();
test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+ test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
return 0;
}
diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.front.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.front.pass.cpp
index 24df3fcad0c5c..bdb239d56145c 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.front.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.front.pass.cpp
@@ -20,6 +20,7 @@
#include "check_assertion.h"
#include "min_allocator.h"
+#include "test_allocator.h"
template <class S>
void test() {
@@ -30,6 +31,7 @@ void test() {
int main(int, char**) {
test<std::string>();
test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+ test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
return 0;
}
diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.index.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.index.pass.cpp
index d26997d8d24c2..1227225bcae3b 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.index.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.index.pass.cpp
@@ -20,6 +20,7 @@
#include "check_assertion.h"
#include "min_allocator.h"
+#include "test_allocator.h"
template <class S>
void test() {
@@ -31,6 +32,7 @@ void test() {
int main(int, char**) {
test<std::string>();
test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+ test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
return 0;
}
diff --git a/libcxx/test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp
index d4a0b318f36d7..f346a2cd2b38a 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp
@@ -35,10 +35,12 @@ int main(int, char**) {
test<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >();
#if TEST_STD_VER >= 11
test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+ test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
#endif
#if TEST_STD_VER > 17
static_assert(test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>>());
static_assert(test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>());
+ static_assert(test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >());
#endif
return 0;
diff --git a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.add.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.add.pass.cpp
index 56c9d63d0dbaf..313681dce1622 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.add.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.add.pass.cpp
@@ -18,6 +18,7 @@
#include "check_assertion.h"
#include "min_allocator.h"
+#include "test_allocator.h"
template <class C>
void test() {
@@ -32,6 +33,7 @@ void test() {
int main(int, char**) {
test<std::string>();
test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+ test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
return 0;
}
diff --git a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.decrement.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.decrement.pass.cpp
index 43a9739bf936f..43d80c554e2f2 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.decrement.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.decrement.pass.cpp
@@ -18,6 +18,7 @@
#include "check_assertion.h"
#include "min_allocator.h"
+#include "test_allocator.h"
template <class C>
void test() {
@@ -31,6 +32,7 @@ void test() {
int main(int, char**) {
test<std::string>();
test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+ test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
return 0;
}
diff --git a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.dereference.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.dereference.pass.cpp
index e2326be021033..7969d766be1a7 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.dereference.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.dereference.pass.cpp
@@ -17,6 +17,7 @@
#include "check_assertion.h"
#include "min_allocator.h"
+#include "test_allocator.h"
template <class C>
void test() {
@@ ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/191023
More information about the libcxx-commits
mailing list