Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2218603/?format=api
{ "id": 2218603, "url": "http://patchwork.ozlabs.org/api/patches/2218603/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260401142749.184089-1-tkaminsk@redhat.com/", "project": { "id": 17, "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api", "name": "GNU Compiler Collection", "link_name": "gcc", "list_id": "gcc-patches.gcc.gnu.org", "list_email": "gcc-patches@gcc.gnu.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260401142749.184089-1-tkaminsk@redhat.com>", "list_archive_url": null, "date": "2026-04-01T14:27:09", "name": "libstdc++: Export explicit instantiations for C++20 members of std::string", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "dfc25f894817d9f05f1d6a119d0f7130f5889fbf", "submitter": { "id": 90409, "url": "http://patchwork.ozlabs.org/api/people/90409/?format=api", "name": "Tomasz Kaminski", "email": "tkaminsk@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/20260401142749.184089-1-tkaminsk@redhat.com/mbox/", "series": [ { "id": 498342, "url": "http://patchwork.ozlabs.org/api/series/498342/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=498342", "date": "2026-04-01T14:27:09", "name": "libstdc++: Export explicit instantiations for C++20 members of std::string", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/498342/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2218603/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2218603/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=WLi/lIER;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=38.145.34.32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)", "sourceware.org;\n\tdkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=WLi/lIER", "sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com", "sourceware.org; spf=pass smtp.mailfrom=redhat.com", "server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.133.124" ], "Received": [ "from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fm6mF0vwFz1yFv\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 02 Apr 2026 01:28:29 +1100 (AEDT)", "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id C5BB54BA23CE\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 1 Apr 2026 14:28:26 +0000 (GMT)", "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by sourceware.org (Postfix) with ESMTP id 44BCA4BA2E31\n for <gcc-patches@gcc.gnu.org>; Wed, 1 Apr 2026 14:27:55 +0000 (GMT)", "from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-650-3C73PsrgPUWux718b-u9_g-1; Wed,\n 01 Apr 2026 10:27:53 -0400", "from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 64B751800281; Wed, 1 Apr 2026 14:27:52 +0000 (UTC)", "from localhost (unknown [10.44.34.29])\n by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id 9D2941954102; Wed, 1 Apr 2026 14:27:51 +0000 (UTC)" ], "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 sourceware.org C5BB54BA23CE", "OpenDKIM Filter v2.11.0 sourceware.org 44BCA4BA2E31" ], "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 44BCA4BA2E31", "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 44BCA4BA2E31", "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1775053675; cv=none;\n b=w6IQEZ7d+e66lecv0WaWlYyFYzLEW6gbViCX0WTW8EiJgOY49YZyilU4uv+8Fif5TGWkqCb9KY/OjDFJRtq9zkhZozTvibEmBEH89fUUlAP5WWzC6zUwpAwxEyy3si+zlvbOdQRMUmmOqv+GkdE3BriaDr6YdK91vxVqcA4CcWQ=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1775053675; c=relaxed/simple;\n bh=ldHY5/coJx1rxsidavx3kreU7JcOKCPDx+Z21mJjvng=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=eSOC/LuOqoeDy2wPHhmTkoeo0wmvl+c1IhMAoNK/lcQrJPA+DOmFVFFY2vBz72R0XUFffv/So383S0MC8nRv/VSobZs9QYFS05KEmb98CW8mJ6fg6XX7z+NedOz0VRFsqdKG+y64tBLgQW+45aCxylG3R/K5wXKM+S4BjpOBPFg=", "ARC-Authentication-Results": "i=1; server2.sourceware.org", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1775053674;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding;\n bh=UNdctfcISt/vGy4sl4bFB9aMeQ2Hcz3o9tzIociBgng=;\n b=WLi/lIER2fHCGKE8j9C8s3gmTRSIcbrCeAZRbrM6LcJ+XczM2zxYA3vSvvK+MsQOkPRYhm\n Mxk/cqtCa+UjzxnCLRtBEdiuE0ReiJERpj33AJ2DsneOEElxXrjP1lpYMcCGqdAI+/RCZL\n IrDp6Oc7hAypejdPxFTsZuta1+43B9c=", "X-MC-Unique": "3C73PsrgPUWux718b-u9_g-1", "X-Mimecast-MFC-AGG-ID": "3C73PsrgPUWux718b-u9_g_1775053672", "From": "=?utf-8?q?Tomasz_Kami=C5=84ski?= <tkaminsk@redhat.com>", "To": "libstdc++@gcc.gnu.org,\n\tgcc-patches@gcc.gnu.org", "Subject": "[PATCH] libstdc++: Export explicit instantiations for C++20 members\n of std::string", "Date": "Wed, 1 Apr 2026 16:27:09 +0200", "Message-ID": "<20260401142749.184089-1-tkaminsk@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.17", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "Uk0aR_Y5RG3HWsENTEuKAOycqBOAsWVCbgXeHbkIomk_1775053672", "X-Mimecast-Originator": "redhat.com", "Content-Transfer-Encoding": "8bit", "content-type": "text/plain; charset=\"US-ASCII\"; x-default=true", "X-BeenThere": "gcc-patches@gcc.gnu.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>", "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>", "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>", "List-Post": "<mailto:gcc-patches@gcc.gnu.org>", "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>", "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>", "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org" }, "content": "The C++20 standard added new starts_with and ends_with members to\nstd::basic_string, which were not previously instantiated in the library.\nThis meant that the extern template declarations had to be disabled for\nC++20 mode. With this patch the new members are instantiated in the\nlibrary and so the explicit instantiation declarations can be used for\nC++20.\n\nThe new members added by C++23 are still not exported, and so the\nexplicit instantiation declarations are still disabled for C++23.\n\nlibstdc++-v3/ChangeLog:\n\n\t* config/abi/pre/gnu.ver (GLIBCXX_3.4): Make string exports\n\tless gready.\n\t(GLIBCXX_3.4.26): Export basic_string starts_with and ends_with\n\tmembers.\n\t* include/bits/basic_string.h: Update __cpluplus checks for C++20.\n\t* include/bits/cow_string.h: Likewise.\n\t* include/bits/basic_string.tcc: Declare explicit instantiations\n\tfor C++20 as well as earlier dialects.\n\t* src/c++20/Makefile.am: Add cow-string-inst.cc and\n\tstring-inst.cc source files.\n\t* src/c++20/Makefile.in: Regenerate.\n\t* src/c++20/string-inst.cc: New file defining explicit\n\tinstantiations for basic_string starts_with and ends_with\n\tfunctions added in C++20\n\t* src/c++20/cow-string-inst.cc: New file.\n---\nUpdating the basic_string for now, so I will get ahold of the process.\nI will work on the format next days. \n\nTesting on x86_64-linux. make check-abi passed, so it seem like I\nhaven't dropped any symbols with my changes.\nOK for trunk when all tests passes?\n\n libstdc++-v3/config/abi/pre/gnu.ver | 26 ++++++++--\n libstdc++-v3/include/bits/basic_string.h | 2 +-\n libstdc++-v3/include/bits/basic_string.tcc | 17 ++++---\n libstdc++-v3/include/bits/cow_string.h | 4 +-\n libstdc++-v3/src/c++20/Makefile.am | 16 +++++-\n libstdc++-v3/src/c++20/Makefile.in | 15 ++++--\n libstdc++-v3/src/c++20/cow-string-inst.cc | 34 +++++++++++++\n libstdc++-v3/src/c++20/string-inst.cc | 57 ++++++++++++++++++++++\n 8 files changed, 151 insertions(+), 20 deletions(-)\n create mode 100644 libstdc++-v3/src/c++20/cow-string-inst.cc\n create mode 100644 libstdc++-v3/src/c++20/string-inst.cc", "diff": "diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver\nindex fb968e122d8..4516934af89 100644\n--- a/libstdc++-v3/config/abi/pre/gnu.ver\n+++ b/libstdc++-v3/config/abi/pre/gnu.ver\n@@ -268,9 +268,11 @@ GLIBCXX_3.4 {\n _ZNSspLE[PRc]*;\n _ZNKSs[0-3][a-b]*;\n _ZNKSs[5-9][a-b]*;\n- _ZNKSs[0-9][d-e]*;\n+ _ZNKSs[0-8][d-e]*;\n _ZNKSs[0-9][g-z]*;\n- _ZNKSs[0-9][0-9][a-z]*;\n+ _ZNKSs11_[MS]_*;\n+ _ZNKSs1[2-8][a-z]*;\n+ _ZNKSs[2-9][0-9][a-z]*;\n _ZNKSs4find*;\n _ZNKSs[abd-z]*;\n _ZNKSs4_Rep12_M_is_leakedEv;\n@@ -339,9 +341,11 @@ GLIBCXX_3.4 {\n _ZNSbIwSt11char_traitsIwESaIwEEpLE[PRw]*;\n _ZNKSbIwSt11char_traitsIwESaIwEE[0-3][a-b]*;\n _ZNKSbIwSt11char_traitsIwESaIwEE[5-9][a-b]*;\n- _ZNKSbIwSt11char_traitsIwESaIwEE[0-9][d-e]*;\n+ _ZNKSbIwSt11char_traitsIwESaIwEE[0-8][d-e]*;\n _ZNKSbIwSt11char_traitsIwESaIwEE[0-9][g-z]*;\n- _ZNKSbIwSt11char_traitsIwESaIwEE[0-9][0-9][a-z]*;\n+ _ZNKSbIwSt11char_traitsIwESaIwEE11_[MS]_*;\n+ _ZNKSbIwSt11char_traitsIwESaIwEE1[2-8][a-z]*;\n+ _ZNKSbIwSt11char_traitsIwESaIwEE[2-9][0-9][a-z]*;\n _ZNKSbIwSt11char_traitsIwESaIwEE[abd-z]*;\n _ZNKSbIwSt11char_traitsIwESaIwEE4find*;\n _ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_leakedEv;\n@@ -1811,7 +1815,9 @@ GLIBCXX_3.4.21 {\n _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]Ev;\n _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]I[PN]*;\n _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[Daip]*;\n- _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[1-9]*;\n+ _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE11_[MS]_*;\n+ _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE1[2-9]*;\n+ _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[2-8]*;\n _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEixE[jmy];\n \n # operator+ for ABI-tagged std::basic_string\n@@ -2587,6 +2593,16 @@ GLIBCXX_3.4.35 {\n _ZNSt12__cow_stringaSEOS_;\n _ZNKSt12__cow_string5c_strEv;\n \n+ # basic_string::starts_with\n+ _ZNKSs11starts_with*;\n+ _ZNKSbIwSt11char_traitsIwESaIwEE11starts_with*;\n+ _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE11starts_with*;\n+\n+ # basic_string::ends_with\n+ _ZNKSs9ends_with*;\n+ _ZNKSbIwSt11char_traitsIwESaIwEE9ends_with*;\n+ _ZNKSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE9ends_with*;\n+\n #if defined (_WIN32) && !defined (__CYGWIN__)\n _ZSt19__get_once_callablev;\n _ZSt15__get_once_callv;\ndiff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h\nindex 202a911f9ef..af4e5d9486f 100644\n--- a/libstdc++-v3/include/bits/basic_string.h\n+++ b/libstdc++-v3/include/bits/basic_string.h\n@@ -1331,7 +1331,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11\n /**\n * Equivalent to shrink_to_fit().\n */\n-#if __cplusplus > 201703L\n+#if __cplusplus >= 202002L\n [[deprecated(\"use shrink_to_fit() instead\")]]\n #endif\n _GLIBCXX20_CONSTEXPR\ndiff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc\nindex a223edf67ac..b00dd550237 100644\n--- a/libstdc++-v3/include/bits/basic_string.tcc\n+++ b/libstdc++-v3/include/bits/basic_string.tcc\n@@ -1031,12 +1031,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n // Inhibit implicit instantiations for required instantiations,\n // which are defined via explicit instantiations elsewhere.\n #if _GLIBCXX_EXTERN_TEMPLATE\n- // The explicit instantiation definitions in src/c++11/string-inst.cc and\n- // src/c++17/string-inst.cc only instantiate the members required for C++17\n- // and earlier standards (so not C++20's starts_with and ends_with).\n- // Suppress the explicit instantiation declarations for C++20, so C++20\n+ // The explicit instantiation definitions in src/c++11/string-inst.cc,\n+ // src/c++17/string-inst.cc and src/c++20/string-inst.cc only instantiate\n+ // the members required for C++20 and earlier standards (so not C++23's\n+ // contains).\n+ // Suppress the explicit instantiation declarations for C++23, so C++23\n // code will implicitly instantiate std::string and std::wstring as needed.\n-# if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0\n+# if __cplusplus <= 202002L && _GLIBCXX_EXTERN_TEMPLATE > 0\n extern template class basic_string<char>;\n # elif ! _GLIBCXX_USE_CXX11_ABI\n // Still need to prevent implicit instantiation of the COW empty rep,\n@@ -1044,7 +1045,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n extern template basic_string<char>::size_type\n basic_string<char>::_Rep::_S_empty_rep_storage[];\n # elif _GLIBCXX_EXTERN_TEMPLATE > 0\n- // Export _M_replace_cold even for C++20.\n+ // Export _M_replace_cold even for C++23.\n extern template void\n basic_string<char>::_M_replace_cold(char *, size_type, const char*,\n \t\t\t\t\tconst size_type, const size_type);\n@@ -1064,13 +1065,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n getline(basic_istream<char>&, string&);\n \n #ifdef _GLIBCXX_USE_WCHAR_T\n-# if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0\n+# if __cplusplus <= 202002L && _GLIBCXX_EXTERN_TEMPLATE > 0\n extern template class basic_string<wchar_t>;\n # elif ! _GLIBCXX_USE_CXX11_ABI\n extern template basic_string<wchar_t>::size_type\n basic_string<wchar_t>::_Rep::_S_empty_rep_storage[];\n # elif _GLIBCXX_EXTERN_TEMPLATE > 0\n- // Export _M_replace_cold even for C++20.\n+ // Export _M_replace_cold even for C++23.\n extern template void\n basic_string<wchar_t>::_M_replace_cold(wchar_t*, size_type, const wchar_t*,\n \t\t\t\t\t const size_type, const size_type);\ndiff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h\nindex 6cf00224372..0dacef129b1 100644\n--- a/libstdc++-v3/include/bits/cow_string.h\n+++ b/libstdc++-v3/include/bits/cow_string.h\n@@ -1080,7 +1080,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n reserve(size_type __res_arg);\n \n /// Equivalent to shrink_to_fit().\n-#if __cplusplus > 201703L\n+#if __cplusplus >= 202002L\n [[deprecated(\"use shrink_to_fit() instead\")]]\n #endif\n void\n@@ -3195,7 +3195,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \treturn __r;\n }\n \n-#if __cplusplus > 201703L\n+#if __cplusplus >= 202002L\n bool\n starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept\n { return __sv_type(this->data(), this->size()).starts_with(__x); }\ndiff --git a/libstdc++-v3/src/c++20/Makefile.am b/libstdc++-v3/src/c++20/Makefile.am\nindex 0061678dc0f..af5d2fa4057 100644\n--- a/libstdc++-v3/src/c++20/Makefile.am\n+++ b/libstdc++-v3/src/c++20/Makefile.am\n@@ -27,10 +27,19 @@ noinst_LTLIBRARIES = libc++20convenience.la\n \n headers =\n \n+if ENABLE_DUAL_ABI\n+extra_string_inst_sources = cow-string-inst.cc\n+else\n+extra_string_inst_sources =\n+endif\n+\n+\n if ENABLE_EXTERN_TEMPLATE\n # XTEMPLATE_FLAGS = -fno-implicit-templates\n inst_sources = \\\n-\tsstream-inst.cc\n+\tsstream-inst.cc \\\n+\tstring-inst.cc \\\n+\t$(extra_string_inst_sources)\n else\n # XTEMPLATE_FLAGS =\n inst_sources =\n@@ -40,6 +49,11 @@ sources = tzdb.cc format.cc atomic.cc clock.cc syncbuf.cc\n \n vpath % $(top_srcdir)/src/c++20\n \n+if ENABLE_DUAL_ABI\n+# These files should be rebuilt if the .cc prerequisite changes.\n+cow-string-inst.lo cow-string-inst.o: string-inst.cc\n+endif\n+\n if USE_STATIC_TZDATA\n tzdata.zi.h: $(top_srcdir)/src/c++20/tzdata.zi\n \techo 'static const char tzdata_chars[] = R\"__libstdcxx__(' > $@.tmp\ndiff --git a/libstdc++-v3/src/c++20/Makefile.in b/libstdc++-v3/src/c++20/Makefile.in\nindex f481ad08edb..a2386ec7ee0 100644\n--- a/libstdc++-v3/src/c++20/Makefile.in\n+++ b/libstdc++-v3/src/c++20/Makefile.in\n@@ -124,9 +124,11 @@ CONFIG_CLEAN_VPATH_FILES =\n LTLIBRARIES = $(noinst_LTLIBRARIES)\n libc__20convenience_la_LIBADD =\n am__objects_1 = tzdb.lo format.lo atomic.lo clock.lo syncbuf.lo\n-@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = sstream-inst.lo\n+@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-string-inst.lo\n+@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_3 = sstream-inst.lo \\\n+@ENABLE_EXTERN_TEMPLATE_TRUE@\tstring-inst.lo $(am__objects_2)\n @GLIBCXX_HOSTED_TRUE@am_libc__20convenience_la_OBJECTS = \\\n-@GLIBCXX_HOSTED_TRUE@\t$(am__objects_1) $(am__objects_2)\n+@GLIBCXX_HOSTED_TRUE@\t$(am__objects_1) $(am__objects_3)\n libc__20convenience_la_OBJECTS = $(am_libc__20convenience_la_OBJECTS)\n AM_V_lt = $(am__v_lt_@AM_V@)\n am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)\n@@ -428,12 +430,16 @@ AM_CPPFLAGS = $(GLIBCXX_INCLUDES) $(CPPFLAGS)\n # Convenience library for C++20 runtime.\n noinst_LTLIBRARIES = libc++20convenience.la\n headers = \n+@ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources = \n+@ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources = cow-string-inst.cc\n # XTEMPLATE_FLAGS =\n @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = \n \n # XTEMPLATE_FLAGS = -fno-implicit-templates\n @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \\\n-@ENABLE_EXTERN_TEMPLATE_TRUE@\tsstream-inst.cc\n+@ENABLE_EXTERN_TEMPLATE_TRUE@\tsstream-inst.cc \\\n+@ENABLE_EXTERN_TEMPLATE_TRUE@\tstring-inst.cc \\\n+@ENABLE_EXTERN_TEMPLATE_TRUE@\t$(extra_string_inst_sources)\n \n sources = tzdb.cc format.cc atomic.cc clock.cc syncbuf.cc\n @GLIBCXX_HOSTED_FALSE@libc__20convenience_la_SOURCES = \n@@ -747,6 +753,9 @@ uninstall-am:\n \n vpath % $(top_srcdir)/src/c++20\n \n+# These files should be rebuilt if the .cc prerequisite changes.\n+@ENABLE_DUAL_ABI_TRUE@cow-string-inst.lo cow-string-inst.o: string-inst.cc\n+\n @USE_STATIC_TZDATA_TRUE@tzdata.zi.h: $(top_srcdir)/src/c++20/tzdata.zi\n @USE_STATIC_TZDATA_TRUE@\techo 'static const char tzdata_chars[] = R\"__libstdcxx__(' > $@.tmp\n @USE_STATIC_TZDATA_TRUE@\tcat $^ >> $@.tmp\ndiff --git a/libstdc++-v3/src/c++20/cow-string-inst.cc b/libstdc++-v3/src/c++20/cow-string-inst.cc\nnew file mode 100644\nindex 00000000000..89d3bdfeab1\n--- /dev/null\n+++ b/libstdc++-v3/src/c++20/cow-string-inst.cc\n@@ -0,0 +1,34 @@\n+// Reference-counted COW string instantiations for C++17 -*- C++ -*-\n+\n+// Copyright (C) 2019-2026 Free Software Foundation, Inc.\n+//\n+// This file is part of the GNU ISO C++ Library. This library is free\n+// software; you can redistribute it and/or modify it under the\n+// terms of the GNU General Public License as published by the\n+// Free Software Foundation; either version 3, or (at your option)\n+// any later version.\n+\n+// This library is distributed in the hope that it will be useful,\n+// but WITHOUT ANY WARRANTY; without even the implied warranty of\n+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n+// GNU General Public License for more details.\n+\n+// Under Section 7 of GPL version 3, you are granted additional\n+// permissions described in the GCC Runtime Library Exception, version\n+// 3.1, as published by the Free Software Foundation.\n+\n+// You should have received a copy of the GNU General Public License and\n+// a copy of the GCC Runtime Library Exception along with this program;\n+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see\n+// <http://www.gnu.org/licenses/>.\n+\n+//\n+// ISO C++ 14882:2017 24 Strings library\n+//\n+\n+#define _GLIBCXX_USE_CXX11_ABI 0\n+#include \"string-inst.cc\"\n+\n+#if ! _GLIBCXX_USE_DUAL_ABI\n+# error This file should not be compiled for this configuration.\n+#endif\ndiff --git a/libstdc++-v3/src/c++20/string-inst.cc b/libstdc++-v3/src/c++20/string-inst.cc\nnew file mode 100644\nindex 00000000000..3f03d4c2d57\n--- /dev/null\n+++ b/libstdc++-v3/src/c++20/string-inst.cc\n@@ -0,0 +1,57 @@\n+// string instantiations for C++17 -*- C++ -*-\n+\n+// Copyright (C) 2019-2026 Free Software Foundation, Inc.\n+//\n+// This file is part of the GNU ISO C++ Library. This library is free\n+// software; you can redistribute it and/or modify it under the\n+// terms of the GNU General Public License as published by the\n+// Free Software Foundation; either version 3, or (at your option)\n+// any later version.\n+\n+// This library is distributed in the hope that it will be useful,\n+// but WITHOUT ANY WARRANTY; without even the implied warranty of\n+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n+// GNU General Public License for more details.\n+\n+// Under Section 7 of GPL version 3, you are granted additional\n+// permissions described in the GCC Runtime Library Exception, version\n+// 3.1, as published by the Free Software Foundation.\n+\n+// You should have received a copy of the GNU General Public License and\n+// a copy of the GCC Runtime Library Exception along with this program;\n+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see\n+// <http://www.gnu.org/licenses/>.\n+\n+//\n+// ISO C++ 14882:2017 24 Strings library\n+//\n+\n+#ifndef _GLIBCXX_USE_CXX11_ABI\n+// Instantiations in this file use the new SSO std::string ABI unless included\n+// by another file which defines _GLIBCXX_USE_CXX11_ABI=0.\n+# define _GLIBCXX_USE_CXX11_ABI 1\n+#endif\n+\n+#include <string>\n+\n+namespace std _GLIBCXX_VISIBILITY(default)\n+{\n+_GLIBCXX_BEGIN_NAMESPACE_VERSION\n+template bool basic_string<char>::starts_with(string_view) const noexcept;\n+template bool basic_string<char>::starts_with(char) const noexcept;\n+template bool basic_string<char>::starts_with(const char*) const noexcept;\n+template bool basic_string<char>::ends_with(string_view) const noexcept;\n+template bool basic_string<char>::ends_with(char) const noexcept;\n+template bool basic_string<char>::ends_with(const char*) const noexcept;\n+\n+#ifdef _GLIBCXX_USE_WCHAR_T\n+template bool basic_string<wchar_t>::starts_with(wstring_view) const noexcept;\n+template bool basic_string<wchar_t>::starts_with(wchar_t) const noexcept;\n+template bool basic_string<wchar_t>::starts_with(const wchar_t*) const noexcept;\n+template bool basic_string<wchar_t>::ends_with(wstring_view) const noexcept;\n+template bool basic_string<wchar_t>::ends_with(wchar_t) const noexcept;\n+template bool basic_string<wchar_t>::ends_with(const wchar_t*) const noexcept;\n+#endif\n+\n+_GLIBCXX_END_NAMESPACE_VERSION\n+} // namespace std\n", "prefixes": [] }