aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-03-07 16:00:01 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2024-08-01 21:56:56 +0100
commit8b8e5ed6cd0f3cfe7cdf93200e47c069fd101984 (patch)
tree9dca9f7a31f54a058001e9d3269035ed0ba4c19f
parent6586b015f1211ccd6e3e89b44dcb2116347edf89 (diff)
downloadgcc-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.h3
-rw-r--r--libstdc++-v3/include/bits/cow_string.h5
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/cons/113841.cc28
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);
+}