diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2024-03-07 16:00:01 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2024-08-01 21:56:56 +0100 |
commit | 8b8e5ed6cd0f3cfe7cdf93200e47c069fd101984 (patch) | |
tree | 9dca9f7a31f54a058001e9d3269035ed0ba4c19f | |
parent | 6586b015f1211ccd6e3e89b44dcb2116347edf89 (diff) | |
download | gcc-8b8e5ed6cd0f3cfe7cdf93200e47c069fd101984.zip gcc-8b8e5ed6cd0f3cfe7cdf93200e47c069fd101984.tar.gz gcc-8b8e5ed6cd0f3cfe7cdf93200e47c069fd101984.tar.bz2 |
libstdc++: Constrain std::basic_string default constructor [PR113841]
This is needed to avoid errors outside the immediate context when
evaluating is_default_constructible_v<basic_string<C, T, A>> when A is
not default constructible.
This change is not sufficient to solve the problem because there are a
large number of member functions which have a default argument that
constructs an allocator.
libstdc++-v3/ChangeLog:
PR libstdc++/113841
* include/bits/basic_string.h (basic_string::basic_string()):
Constrain so that it's only present if the allocator is default
constructible.
* include/bits/cow_string.h (basic_string::basic_string()):
Likewise.
* testsuite/21_strings/basic_string/cons/113841.cc: New test.
-rw-r--r-- | libstdc++-v3/include/bits/basic_string.h | 3 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/cow_string.h | 5 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/21_strings/basic_string/cons/113841.cc | 28 |
3 files changed, 36 insertions, 0 deletions
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 8a695a4..944bd23 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -526,6 +526,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX20_CONSTEXPR basic_string() _GLIBCXX_NOEXCEPT_IF(is_nothrow_default_constructible<_Alloc>::value) +#if __cpp_concepts && __glibcxx_type_trait_variable_templates + requires is_default_constructible_v<_Alloc> +#endif : _M_dataplus(_M_local_data()) { _M_init_local_buf(); diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h index 75a2d88..2298844 100644 --- a/libstdc++-v3/include/bits/cow_string.h +++ b/libstdc++-v3/include/bits/cow_string.h @@ -515,6 +515,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_string() #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 _GLIBCXX_NOEXCEPT +#endif +#if __cpp_concepts && __glibcxx_type_trait_variable_templates + requires is_default_constructible_v<_Alloc> +#endif +#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) #else : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/cons/113841.cc b/libstdc++-v3/testsuite/21_strings/basic_string/cons/113841.cc new file mode 100644 index 0000000..5a08610 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/113841.cc @@ -0,0 +1,28 @@ +// { dg-do compile { target c++20 } } + +#include <string> + +template<typename T> +struct Alloc +{ + using value_type = T; + + Alloc(int) { } // not default constructible + + template<typename U> Alloc(const Alloc<U>&) { } + + T* allocate(std::size_t n) { return std::allocator<T>().allocate(n); } + void deallocate(T* p, std::size_t n) { std::allocator<T>().deallocate(p, n); } +}; + +template<typename T> struct wrap { T t; }; + +template<typename T> void do_adl(T&) { } + +void test_pr113841() +{ + using Tr = std::char_traits<char>; + using test_type = std::basic_string<char, Tr, Alloc<char>>; + std::pair<const int, wrap<test_type>>* h = nullptr; + do_adl(h); +} |