diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index fb968e122d8..2ff2aa02383 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -268,9 +268,11 @@ GLIBCXX_3.4 { _ZNSspLE[PRc]*; _ZNKSs[0-3][a-b]*; _ZNKSs[5-9][a-b]*; - _ZNKSs[0-9][d-e]*; + _ZNKSs[0-8][d-e]*; _ZNKSs[0-9][g-z]*; - _ZNKSs[0-9][0-9][a-z]*; + _ZNKSs11_[MS]_*; + _ZNKSs1[2-8][a-z]*; + _ZNKSs[2-9][0-9][a-z]*; _ZNKSs4find*; _ZNKSs[abd-z]*; _ZNKSs4_Rep12_M_is_leakedEv; @@ -339,9 +341,11 @@ GLIBCXX_3.4 { _ZNSbIwSt11char_traitsIwESaIwEEpLE[PRw]*; _ZNKSbIwSt11char_traitsIwESaIwEE[0-3][a-b]*; _ZNKSbIwSt11char_traitsIwESaIwEE[5-9][a-b]*; - _ZNKSbIwSt11char_traitsIwESaIwEE[0-9][d-e]*; + _ZNKSbIwSt11char_traitsIwESaIwEE[0-8][d-e]*; _ZNKSbIwSt11char_traitsIwESaIwEE[0-9][g-z]*; - _ZNKSbIwSt11char_traitsIwESaIwEE[0-9][0-9][a-z]*; + _ZNKSbIwSt11char_traitsIwESaIwEE11_[MS]_*; + _ZNKSbIwSt11char_traitsIwESaIwEE1[2-8][a-z]*; + _ZNKSbIwSt11char_traitsIwESaIwEE[2-9][0-9][a-z]*; _ZNKSbIwSt11char_traitsIwESaIwEE[abd-z]*; _ZNKSbIwSt11char_traitsIwESaIwEE4find*; _ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_leakedEv; @@ -1811,7 +1815,9 @@ GLIBCXX_3.4.21 { _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]Ev; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]I[PN]*; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[Daip]*; - _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[1-9]*; + _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE11_[MS]_*; + _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE1[2-9]*; + _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[2-8]*; _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEixE[jmy]; # operator+ for ABI-tagged std::basic_string @@ -2587,6 +2593,21 @@ GLIBCXX_3.4.35 { _ZNSt12__cow_stringaSEOS_; _ZNKSt12__cow_string5c_strEv; + # basic_string::starts_with + _ZNKSs11starts_with*; + _ZNKSbIwSt11char_traitsIwESaIwEE11starts_with*; + _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE11starts_with*; + + # basic_string::ends_with + _ZNKSs9ends_with*; + _ZNKSbIwSt11char_traitsIwESaIwEE9ends_with*; + _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE9ends_with*; + + # basic_string::basic_string() noexcept is_default_constructible; + _ZNSsC[12]EvQ26is_default_constructible_vIT1_E; + _ZNSbIwSt11char_traitsIwESaIwEEC[12]EvQ26is_default_constructible_vIT1_E; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[1-2]EvQ26is_default_constructible_vIT1_E; + #if defined (_WIN32) && !defined (__CYGWIN__) _ZSt19__get_once_callablev; _ZSt15__get_once_callv; diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 202a911f9ef..af4e5d9486f 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -1331,7 +1331,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 /** * Equivalent to shrink_to_fit(). */ -#if __cplusplus > 201703L +#if __cplusplus >= 202002L [[deprecated("use shrink_to_fit() instead")]] #endif _GLIBCXX20_CONSTEXPR diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index a223edf67ac..b00dd550237 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -1031,12 +1031,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE - // The explicit instantiation definitions in src/c++11/string-inst.cc and - // src/c++17/string-inst.cc only instantiate the members required for C++17 - // and earlier standards (so not C++20's starts_with and ends_with). - // Suppress the explicit instantiation declarations for C++20, so C++20 + // The explicit instantiation definitions in src/c++11/string-inst.cc, + // src/c++17/string-inst.cc and src/c++20/string-inst.cc only instantiate + // the members required for C++20 and earlier standards (so not C++23's + // contains). + // Suppress the explicit instantiation declarations for C++23, so C++23 // code will implicitly instantiate std::string and std::wstring as needed. -# if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0 +# if __cplusplus <= 202002L && _GLIBCXX_EXTERN_TEMPLATE > 0 extern template class basic_string; # elif ! _GLIBCXX_USE_CXX11_ABI // Still need to prevent implicit instantiation of the COW empty rep, @@ -1044,7 +1045,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION extern template basic_string::size_type basic_string::_Rep::_S_empty_rep_storage[]; # elif _GLIBCXX_EXTERN_TEMPLATE > 0 - // Export _M_replace_cold even for C++20. + // Export _M_replace_cold even for C++23. extern template void basic_string::_M_replace_cold(char *, size_type, const char*, const size_type, const size_type); @@ -1064,13 +1065,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION getline(basic_istream&, string&); #ifdef _GLIBCXX_USE_WCHAR_T -# if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0 +# if __cplusplus <= 202002L && _GLIBCXX_EXTERN_TEMPLATE > 0 extern template class basic_string; # elif ! _GLIBCXX_USE_CXX11_ABI extern template basic_string::size_type basic_string::_Rep::_S_empty_rep_storage[]; # elif _GLIBCXX_EXTERN_TEMPLATE > 0 - // Export _M_replace_cold even for C++20. + // Export _M_replace_cold even for C++23. extern template void basic_string::_M_replace_cold(wchar_t*, size_type, const wchar_t*, const size_type, const size_type); diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h index df71185e556..7c945f6b998 100644 --- a/libstdc++-v3/include/bits/cow_string.h +++ b/libstdc++-v3/include/bits/cow_string.h @@ -1080,7 +1080,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION reserve(size_type __res_arg); /// Equivalent to shrink_to_fit(). -#if __cplusplus > 201703L +#if __cplusplus >= 202002L [[deprecated("use shrink_to_fit() instead")]] #endif void @@ -3194,7 +3194,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __r; } -#if __cplusplus > 201703L +#if __cplusplus >= 202002L bool starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept { return __sv_type(this->data(), this->size()).starts_with(__x); } diff --git a/libstdc++-v3/src/c++20/Makefile.am b/libstdc++-v3/src/c++20/Makefile.am index 0061678dc0f..af5d2fa4057 100644 --- a/libstdc++-v3/src/c++20/Makefile.am +++ b/libstdc++-v3/src/c++20/Makefile.am @@ -27,10 +27,19 @@ noinst_LTLIBRARIES = libc++20convenience.la headers = +if ENABLE_DUAL_ABI +extra_string_inst_sources = cow-string-inst.cc +else +extra_string_inst_sources = +endif + + if ENABLE_EXTERN_TEMPLATE # XTEMPLATE_FLAGS = -fno-implicit-templates inst_sources = \ - sstream-inst.cc + sstream-inst.cc \ + string-inst.cc \ + $(extra_string_inst_sources) else # XTEMPLATE_FLAGS = inst_sources = @@ -40,6 +49,11 @@ sources = tzdb.cc format.cc atomic.cc clock.cc syncbuf.cc vpath % $(top_srcdir)/src/c++20 +if ENABLE_DUAL_ABI +# These files should be rebuilt if the .cc prerequisite changes. +cow-string-inst.lo cow-string-inst.o: string-inst.cc +endif + if USE_STATIC_TZDATA tzdata.zi.h: $(top_srcdir)/src/c++20/tzdata.zi echo 'static const char tzdata_chars[] = R"__libstdcxx__(' > $@.tmp diff --git a/libstdc++-v3/src/c++20/Makefile.in b/libstdc++-v3/src/c++20/Makefile.in index f481ad08edb..a2386ec7ee0 100644 --- a/libstdc++-v3/src/c++20/Makefile.in +++ b/libstdc++-v3/src/c++20/Makefile.in @@ -124,9 +124,11 @@ CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libc__20convenience_la_LIBADD = am__objects_1 = tzdb.lo format.lo atomic.lo clock.lo syncbuf.lo -@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = sstream-inst.lo +@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-string-inst.lo +@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_3 = sstream-inst.lo \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ string-inst.lo $(am__objects_2) @GLIBCXX_HOSTED_TRUE@am_libc__20convenience_la_OBJECTS = \ -@GLIBCXX_HOSTED_TRUE@ $(am__objects_1) $(am__objects_2) +@GLIBCXX_HOSTED_TRUE@ $(am__objects_1) $(am__objects_3) libc__20convenience_la_OBJECTS = $(am_libc__20convenience_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -428,12 +430,16 @@ AM_CPPFLAGS = $(GLIBCXX_INCLUDES) $(CPPFLAGS) # Convenience library for C++20 runtime. noinst_LTLIBRARIES = libc++20convenience.la headers = +@ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources = +@ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources = cow-string-inst.cc # XTEMPLATE_FLAGS = @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = # XTEMPLATE_FLAGS = -fno-implicit-templates @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \ -@ENABLE_EXTERN_TEMPLATE_TRUE@ sstream-inst.cc +@ENABLE_EXTERN_TEMPLATE_TRUE@ sstream-inst.cc \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ string-inst.cc \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ $(extra_string_inst_sources) sources = tzdb.cc format.cc atomic.cc clock.cc syncbuf.cc @GLIBCXX_HOSTED_FALSE@libc__20convenience_la_SOURCES = @@ -747,6 +753,9 @@ uninstall-am: vpath % $(top_srcdir)/src/c++20 +# These files should be rebuilt if the .cc prerequisite changes. +@ENABLE_DUAL_ABI_TRUE@cow-string-inst.lo cow-string-inst.o: string-inst.cc + @USE_STATIC_TZDATA_TRUE@tzdata.zi.h: $(top_srcdir)/src/c++20/tzdata.zi @USE_STATIC_TZDATA_TRUE@ echo 'static const char tzdata_chars[] = R"__libstdcxx__(' > $@.tmp @USE_STATIC_TZDATA_TRUE@ cat $^ >> $@.tmp diff --git a/libstdc++-v3/src/c++20/cow-string-inst.cc b/libstdc++-v3/src/c++20/cow-string-inst.cc new file mode 100644 index 00000000000..f3f411f5d0a --- /dev/null +++ b/libstdc++-v3/src/c++20/cow-string-inst.cc @@ -0,0 +1,34 @@ +// Reference-counted COW string instantiations for C++20 -*- C++ -*- + +// Copyright (C) 2026 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882:2020 21 Strings library +// + +#define _GLIBCXX_USE_CXX11_ABI 0 +#include "string-inst.cc" + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif diff --git a/libstdc++-v3/src/c++20/string-inst.cc b/libstdc++-v3/src/c++20/string-inst.cc new file mode 100644 index 00000000000..2bdd77c78a4 --- /dev/null +++ b/libstdc++-v3/src/c++20/string-inst.cc @@ -0,0 +1,59 @@ +// string instantiations for C++20 -*- C++ -*- + +// Copyright (C) 2026 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882:2020 21 Strings library +// + +#ifndef _GLIBCXX_USE_CXX11_ABI +// Instantiations in this file use the new SSO std::string ABI unless included +// by another file which defines _GLIBCXX_USE_CXX11_ABI=0. +# define _GLIBCXX_USE_CXX11_ABI 1 +#endif + +#include + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION +template basic_string::basic_string() noexcept; +template bool basic_string::starts_with(string_view) const noexcept; +template bool basic_string::starts_with(char) const noexcept; +template bool basic_string::starts_with(const char*) const noexcept; +template bool basic_string::ends_with(string_view) const noexcept; +template bool basic_string::ends_with(char) const noexcept; +template bool basic_string::ends_with(const char*) const noexcept; + +#ifdef _GLIBCXX_USE_WCHAR_T +template basic_string::basic_string() noexcept; +template bool basic_string::starts_with(wstring_view) const noexcept; +template bool basic_string::starts_with(wchar_t) const noexcept; +template bool basic_string::starts_with(const wchar_t*) const noexcept; +template bool basic_string::ends_with(wstring_view) const noexcept; +template bool basic_string::ends_with(wchar_t) const noexcept; +template bool basic_string::ends_with(const wchar_t*) const noexcept; +#endif + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std