@@ -4230,7 +4230,7 @@ changequote([,])dnl
fi
# For libtool versioning info, format is CURRENT:REVISION:AGE
-libtool_VERSION=6:33:0
+libtool_VERSION=6:34:0
# Everything parsed; figure out what files and settings to use.
case $enable_symvers in
@@ -109,7 +109,11 @@ GLIBCXX_3.4 {
std::[j-k]*;
# std::length_error::l*;
# std::length_error::~l*;
- std::locale::[A-Za-e]*;
+ # std::locale::[A-Za-d]*;
+ std::locale::all;
+ std::locale::classic*;
+ std::locale::collate;
+ std::locale::ctype;
std::locale::facet::[A-Za-z]*;
std::locale::facet::_S_get_c_locale*;
std::locale::facet::_S_clone_c_locale*;
@@ -168,7 +172,7 @@ GLIBCXX_3.4 {
std::strstream*;
std::strstreambuf*;
# std::t[a-q]*;
- std::t[a-g]*;
+ std::terminate*;
std::th[a-h]*;
std::th[j-q]*;
std::th[s-z]*;
@@ -2528,6 +2532,14 @@ GLIBCXX_3.4.33 {
_ZNKSt12__basic_fileIcE13native_handleEv;
} GLIBCXX_3.4.32;
+# GCC 15.1.0
+GLIBCXX_3.4.34 {
+ # std::__format::__with_encoding_conversion
+ _ZNSt8__format26__with_encoding_conversionERKSt6locale;
+ # std::__format::__locale_encoding_to_utf8
+ _ZNSt8__format25__locale_encoding_to_utf8ERKSt6localeSt17basic_string_viewIcSt11char_traitsIcEEPv;
+} GLIBCXX_3.4.33;
+
# Symbols in the support library (libsupc++) have their own tag.
CXXABI_1.3 {
@@ -51040,7 +51040,7 @@ $as_echo "$as_me: WARNING: === Symbol versioning will be disabled." >&2;}
fi
# For libtool versioning info, format is CURRENT:REVISION:AGE
-libtool_VERSION=6:33:0
+libtool_VERSION=6:34:0
# Everything parsed; figure out what files and settings to use.
case $enable_symvers in
@@ -38,8 +38,10 @@
#include <iomanip> // setw, setfill
#include <format>
#include <charconv> // from_chars
+#include <stdexcept> // __sso_string
#include <bits/streambuf_iterator.h>
+#include <bits/unique_ptr.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -211,6 +213,20 @@ namespace __format
struct _ChronoSpec : _Spec<_CharT>
{
basic_string_view<_CharT> _M_chrono_specs;
+
+ // Use one of the reserved bits in __format::_Spec<C>.
+ // This indicates that a locale-dependent conversion specifier such as
+ // %a is used in the chrono-specs. This is not the same as the
+ // _Spec<C>::_M_localized member which indicates that "L" was present
+ // in the format-spec, e.g. "{:L%a}" is localized and locale-specific,
+ // but "{:L}" is only localized and "{:%a}" is only locale-specific.
+ constexpr bool
+ _M_locale_specific() const noexcept
+ { return this->_M_reserved; }
+
+ constexpr void
+ _M_locale_specific(bool __b) noexcept
+ { this->_M_reserved = __b; }
};
// Represents the information provided by a chrono type.
@@ -305,11 +321,12 @@ namespace __format
const auto __chrono_specs = __first++; // Skip leading '%'
if (*__chrono_specs != '%')
__throw_format_error("chrono format error: no '%' at start of "
- "chrono-specs");
+ "chrono-specs");
_CharT __mod{};
bool __conv = true;
int __needed = 0;
+ bool __locale_specific = false;
while (__first != __last)
{
@@ -322,15 +339,18 @@ namespace __format
case 'a':
case 'A':
__needed = _Weekday;
+ __locale_specific = true;
break;
case 'b':
case 'h':
case 'B':
__needed = _Month;
+ __locale_specific = true;
break;
case 'c':
__needed = _DateTime;
__allowed_mods = _Mod_E;
+ __locale_specific = true;
break;
case 'C':
__needed = _Year;
@@ -368,6 +388,8 @@ namespace __format
break;
case 'p':
case 'r':
+ __locale_specific = true;
+ [[fallthrough]];
case 'R':
case 'T':
__needed = _TimeOfDay;
@@ -393,10 +415,12 @@ namespace __format
break;
case 'x':
__needed = _Date;
+ __locale_specific = true;
__allowed_mods = _Mod_E;
break;
case 'X':
__needed = _TimeOfDay;
+ __locale_specific = true;
__allowed_mods = _Mod_E;
break;
case 'y':
@@ -436,6 +460,8 @@ namespace __format
|| (__mod == 'O' && !(__allowed_mods & _Mod_O)))
__throw_format_error("chrono format error: invalid "
" modifier in chrono-specs");
+ if (__mod && __c != 'z')
+ __locale_specific = true;
__mod = _CharT();
if ((__parts & __needed) != __needed)
@@ -467,6 +493,7 @@ namespace __format
_M_spec = __spec;
_M_spec._M_chrono_specs
= __string_view(__chrono_specs, __first - __chrono_specs);
+ _M_spec._M_locale_specific(__locale_specific);
return __first;
}
@@ -486,6 +513,24 @@ namespace __format
if (__first == __last)
return _M_format_to_ostream(__t, __fc, __is_neg);
+#if __glibcxx_format >= 202207L // C++ >= 23
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3565. Handling of encodings in localized formatting
+ // of chrono types is underspecified
+ if constexpr (is_same_v<_CharT, char>)
+ if constexpr (__unicode::__literal_encoding_is_utf8())
+ if (_M_spec._M_localized && _M_spec._M_locale_specific())
+ {
+ extern locale __with_encoding_conversion(const locale&);
+
+ // Allocate and cache the necessary state to convert strings
+ // in the locale's encoding to UTF-8.
+ locale __loc = __fc.locale();
+ if (__loc != locale::classic())
+ __fc._M_loc = __with_encoding_conversion(__loc);
+ }
+#endif
+
_Sink_iter<_CharT> __out;
__format::_Str_sink<_CharT> __sink;
bool __write_direct = false;
@@ -742,6 +787,30 @@ namespace __format
static constexpr _CharT _S_space = _S_chars[14];
static constexpr const _CharT* _S_empty_spec = _S_chars + 15;
+ template<typename _OutIter>
+ _OutIter
+ _M_write(_OutIter __out, const locale& __loc, __string_view __s) const
+ {
+#if __glibcxx_format >= 202207L // C++ >= 20
+ __sso_string __buf;
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3565. Handling of encodings in localized formatting
+ // of chrono types is underspecified
+ if constexpr (is_same_v<_CharT, char>)
+ if constexpr (__unicode::__literal_encoding_is_utf8())
+ if (_M_spec._M_localized && _M_spec._M_locale_specific()
+ && __loc != locale::classic())
+ {
+ extern string_view
+ __locale_encoding_to_utf8(const std::locale&, string_view,
+ void*);
+
+ __s = __locale_encoding_to_utf8(__loc, __s, &__buf);
+ }
+#endif
+ return __format::__write(std::move(__out), __s);
+ }
+
template<typename _Tp, typename _FormatContext>
typename _FormatContext::iterator
_M_a_A(const _Tp& __t, typename _FormatContext::iterator __out,
@@ -761,7 +830,7 @@ namespace __format
else
__tp._M_days_abbreviated(__days);
__string_view __str(__days[__wd.c_encoding()]);
- return __format::__write(std::move(__out), __str);
+ return _M_write(std::move(__out), __loc, __str);
}
template<typename _Tp, typename _FormatContext>
@@ -782,7 +851,7 @@ namespace __format
else
__tp._M_months_abbreviated(__months);
__string_view __str(__months[(unsigned)__m - 1]);
- return __format::__write(std::move(__out), __str);
+ return _M_write(std::move(__out), __loc, __str);
}
template<typename _Tp, typename _FormatContext>
@@ -1059,8 +1128,8 @@ namespace __format
const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
const _CharT* __ampm[2];
__tp._M_am_pm(__ampm);
- return std::format_to(std::move(__out), _S_empty_spec,
- __ampm[__hms.hours().count() >= 12]);
+ return _M_write(std::move(__out), __loc,
+ __ampm[__hms.hours().count() >= 12]);
}
template<typename _Tp, typename _FormatContext>
@@ -1095,8 +1164,9 @@ namespace __format
basic_string<_CharT> __fmt(_S_empty_spec);
__fmt.insert(1u, 1u, _S_colon);
__fmt.insert(2u, __ampm_fmt);
- return std::vformat_to(std::move(__out), __fmt,
- std::make_format_args<_FormatContext>(__t));
+ using _FmtStr = _Runtime_format_string<_CharT>;
+ return _M_write(std::move(__out), __loc,
+ std::format(__loc, _FmtStr(__fmt), __t));
}
template<typename _Tp, typename _FormatContext>
@@ -1279,8 +1349,9 @@ namespace __format
basic_string<_CharT> __fmt(_S_empty_spec);
__fmt.insert(1u, 1u, _S_colon);
__fmt.insert(2u, __rep);
- return std::vformat_to(std::move(__out), __fmt,
- std::make_format_args<_FormatContext>(__t));
+ using _FmtStr = _Runtime_format_string<_CharT>;
+ return _M_write(std::move(__out), __loc,
+ std::format(__loc, _FmtStr(__fmt), __t));
}
template<typename _Tp, typename _FormatContext>
@@ -1302,8 +1373,9 @@ namespace __format
basic_string<_CharT> __fmt(_S_empty_spec);
__fmt.insert(1u, 1u, _S_colon);
__fmt.insert(2u, __rep);
- return std::vformat_to(std::move(__out), __fmt,
- std::make_format_args<_FormatContext>(__t));
+ using _FmtStr = _Runtime_format_string<_CharT>;
+ return _M_write(std::move(__out), __loc,
+ std::format(__loc, _FmtStr(__fmt), __t));
}
template<typename _Tp, typename _FormatContext>
@@ -1580,7 +1652,7 @@ namespace __format
const auto& __tp = use_facet<time_put<_CharT>>(__loc);
__tp.put(__os, __os, _S_space, &__tm, __fmt, __mod);
if (__os)
- __out = __format::__write(std::move(__out), __os.view());
+ __out = _M_write(std::move(__out), __loc, __os.view());
return __out;
}
};
@@ -1161,16 +1161,27 @@ ftms = {
};
ftms = {
+ name = format;
+ // 202311 P2918R2 Runtime format strings II
+ // values = {
+ // v = 202311;
+ // cxxmin = 26;
+ // hosted = yes;
+ // };
+ // 202304 P2510R3 Formatting pointers
+ // 202305 P2757R3 Type checking format args
+ // 202306 P2637R3 Member visit
+ values = {
+ v = 202304;
+ cxxmin = 23;
+ hosted = yes;
+ };
// 201907 Text Formatting, Integration of chrono, printf corner cases.
// 202106 std::format improvements.
// 202110 Fixing locale handling in chrono formatters, generator-like types.
// 202207 Encodings in localized formatting of chrono, basic-format-string.
- // 202207 P2286R8 Formatting Ranges
- // 202207 P2585R1 Improving default container formatting
- // TODO: #define __cpp_lib_format_ranges 202207L
- name = format;
values = {
- v = 202110;
+ v = 202207;
cxxmin = 20;
hosted = yes;
};
@@ -1374,6 +1385,19 @@ ftms = {
};
};
+// ftms = {
+ // name = format_ranges;
+ // 202207 P2286R8 Formatting Ranges
+ // 202207 P2585R1 Improving default container formatting
+ // LWG3750 Too many papers bump __cpp_lib_format
+ // TODO: #define __cpp_lib_format_ranges 202207L
+ // values = {
+ // v = 202207;
+ // cxxmin = 23;
+ // hosted = yes;
+ // };
+// };
+
ftms = {
name = freestanding_algorithm;
values = {
@@ -1304,10 +1304,15 @@
#undef __glibcxx_want_barrier
#if !defined(__cpp_lib_format)
-# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
-# define __glibcxx_format 202110L
+# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
+# define __glibcxx_format 202304L
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_format)
-# define __cpp_lib_format 202110L
+# define __cpp_lib_format 202304L
+# endif
+# elif (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
+# define __glibcxx_format 202207L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_format)
+# define __cpp_lib_format 202207L
# endif
# endif
#endif /* !defined(__cpp_lib_format) && defined(__glibcxx_want_format) */
@@ -2342,10 +2342,10 @@ namespace __format
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// P2510R3 Formatting pointers
-#if __cplusplus > 202302L || ! defined __STRICT_ANSI__
-#define _GLIBCXX_P2518R3 1
+#if __glibcxx_format >= 202304L || ! defined __STRICT_ANSI__
+# define _GLIBCXX_P2518R3 1
#else
-#define _GLIBCXX_P2518R3 0
+# define _GLIBCXX_P2518R3 0
#endif
#if _GLIBCXX_P2518R3
@@ -3821,6 +3821,9 @@ namespace __format
__do_vformat_to(_Out, basic_string_view<_CharT>,
const basic_format_args<_Context>&,
const locale* = nullptr);
+
+ template<typename _CharT> struct __formatter_chrono;
+
} // namespace __format
/// @endcond
@@ -3831,6 +3834,11 @@ namespace __format
* this class template explicitly. For typical uses of `std::format` the
* library will use the specializations `std::format_context` (for `char`)
* and `std::wformat_context` (for `wchar_t`).
+ *
+ * You are not allowed to define partial or explicit specializations of
+ * this class template.
+ *
+ * @since C++20
*/
template<typename _Out, typename _CharT>
class basic_format_context
@@ -3863,6 +3871,8 @@ namespace __format
const basic_format_args<_Context2>&,
const locale*);
+ friend __format::__formatter_chrono<_CharT>;
+
public:
~basic_format_context() = default;
@@ -36,7 +36,7 @@ else
inst_sources =
endif
-sources = tzdb.cc
+sources = tzdb.cc format.cc
vpath % $(top_srcdir)/src/c++20
@@ -53,6 +53,12 @@ tzdb.o: tzdb.cc tzdata.zi.h
$(CXXCOMPILE) -I. -c $<
endif
+# This needs access to std::text_encoding and to the internals of std::locale.
+format.lo: format.cc
+ $(LTCXXCOMPILE) -std=gnu++26 -fno-access-control -c $<
+format.o: format.cc
+ $(CXXCOMPILE) -std=gnu++26 -fno-access-control -c $<
+
if GLIBCXX_HOSTED
libc__20convenience_la_SOURCES = $(sources) $(inst_sources)
else
@@ -121,7 +121,7 @@ CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libc__20convenience_la_LIBADD =
-am__objects_1 = tzdb.lo
+am__objects_1 = tzdb.lo format.lo
@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = sstream-inst.lo
@GLIBCXX_HOSTED_TRUE@am_libc__20convenience_la_OBJECTS = \
@GLIBCXX_HOSTED_TRUE@ $(am__objects_1) $(am__objects_2)
@@ -432,7 +432,7 @@ headers =
@ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
@ENABLE_EXTERN_TEMPLATE_TRUE@ sstream-inst.cc
-sources = tzdb.cc
+sources = tzdb.cc format.cc
@GLIBCXX_HOSTED_FALSE@libc__20convenience_la_SOURCES =
@GLIBCXX_HOSTED_TRUE@libc__20convenience_la_SOURCES = $(sources) $(inst_sources)
@@ -755,6 +755,12 @@ vpath % $(top_srcdir)/src/c++20
@USE_STATIC_TZDATA_TRUE@tzdb.o: tzdb.cc tzdata.zi.h
@USE_STATIC_TZDATA_TRUE@ $(CXXCOMPILE) -I. -c $<
+# This needs access to std::text_encoding and to the internals of std::locale.
+format.lo: format.cc
+ $(LTCXXCOMPILE) -std=gnu++26 -fno-access-control -c $<
+format.o: format.cc
+ $(CXXCOMPILE) -std=gnu++26 -fno-access-control -c $<
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
new file mode 100644
@@ -0,0 +1,174 @@
+// Definitions for <chrono> formatting -*- C++ -*-
+
+// Copyright The GNU Toolchain Authors.
+//
+// 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
+// <http://www.gnu.org/licenses/>.
+
+#define _GLIBCXX_USE_CXX11_ABI 1
+#include "../c++26/text_encoding.cc"
+
+#if defined _GLIBCXX_USE_NL_LANGINFO_L && defined _GLIBCXX_HAVE_ICONV
+# include <format>
+# include <chrono>
+# include <memory> // make_unique
+# include <string.h> // strlen, strcpy
+# include <iconv.h>
+# include <errno.h>
+#endif
+
+namespace std
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+namespace __format
+{
+// Helpers for P2419R2
+// (Clarify handling of encodings in localized formatting of chrono types)
+// Convert a string from the locale's charset to UTF-8.
+
+namespace
+{
+// A non-standard locale::facet that caches the locale's std::text_encoding
+// and an iconv descriptor for converting from that encoding to UTF-8.
+struct __encoding : locale::facet
+{
+ static locale::id id;
+
+ explicit
+ __encoding(const text_encoding& enc, size_t refs = 0)
+ : facet(refs), _M_enc(enc)
+ {
+#if defined _GLIBCXX_HAVE_ICONV
+ if (enc != text_encoding::UTF8 && enc != text_encoding::ASCII)
+ _M_cd = ::iconv_open("UTF-8", enc.name());
+#endif
+ }
+
+ ~__encoding()
+ {
+#if defined _GLIBCXX_HAVE_ICONV
+ if (_M_has_desc())
+ ::iconv_close(_M_cd);
+#endif
+ }
+
+ bool _M_has_desc() const
+ {
+#if defined _GLIBCXX_HAVE_ICONV
+ return _M_cd != (::iconv_t)-1;
+#else
+ return false;
+#endif
+ }
+
+ text_encoding _M_enc;
+#if defined _GLIBCXX_HAVE_ICONV
+ ::iconv_t _M_cd = (::iconv_t)-1;
+#endif
+};
+
+locale::id __encoding::id;
+} // namespace
+
+std::locale
+__with_encoding_conversion(const std::locale& loc)
+{
+#if defined _GLIBCXX_USE_NL_LANGINFO_L && __CHAR_BIT__ == 8
+ if (std::__try_use_facet<__encoding>(loc))
+ return loc;
+
+ string name = loc.name();
+ if (name == "C" || name == "*")
+ return loc;
+
+ text_encoding locenc = __locale_encoding(name.c_str());
+
+ if (locenc == text_encoding::UTF8 || locenc == text_encoding::ASCII
+ || locenc == text_encoding::unknown)
+ return loc;
+
+ auto impl = std::make_unique<locale::_Impl>(*loc._M_impl, 1);
+ auto facetp = std::make_unique<__encoding>(locenc);
+ locale loc2(loc, facetp.get()); // FIXME: PR libstdc++/113704
+ facetp.release();
+ // FIXME: Ideally we wouldn't need to reallocate this string again,
+ // just don't delete[] it in the locale(locale, Facet*) constructor.
+ if (const char* name = loc._M_impl->_M_names[0])
+ {
+ loc2._M_impl->_M_names[0] = new char[strlen(name) + 1];
+ strcpy(loc2._M_impl->_M_names[0], name);
+ }
+ return loc2;
+#else
+ return loc;
+#endif
+}
+
+string_view
+__locale_encoding_to_utf8(const std::locale& loc, string_view str,
+ void* poutbuf)
+{
+#if defined _GLIBCXX_USE_NL_LANGINFO_L && __CHAR_BIT__ == 8 \
+ && _GLIBCXX_HAVE_ICONV
+ string& outbuf = *static_cast<string*>(poutbuf);
+ // Don't need to use __try_use_facet with its dynamic_cast<__encoding*>,
+ // since we know there are no types derived from __encoding. If the array
+ // element is non-null, we have the facet.
+ auto id = __encoding::id._M_id();
+ auto enc_facet = static_cast<const __encoding*>(loc._M_impl->_M_facets[id]);
+ if (!enc_facet || !enc_facet->_M_has_desc())
+ return str;
+
+ size_t inbytesleft = str.size();
+ size_t written = 0;
+ bool done = false;
+
+ auto overwrite = [&](char* p, size_t n) {
+ auto inbytes = const_cast<char*>(str.data()) + str.size() - inbytesleft;
+ char* outbytes = p + written;
+ size_t outbytesleft = n - written;
+ size_t res = ::iconv(enc_facet->_M_cd, &inbytes, &inbytesleft,
+ &outbytes, &outbytesleft);
+ if (res == (size_t)-1)
+ {
+ if (errno != E2BIG)
+ {
+ done = true;
+ return 0zu;
+ }
+ }
+ else
+ done = true;
+ written = outbytes - p;
+ return written;
+ };
+ do
+ outbuf.resize_and_overwrite(outbuf.capacity() + (inbytesleft * 3 / 2),
+ overwrite);
+ while (!done);
+ if (outbuf.size())
+ str = outbuf;
+#endif // USE_NL_LANGINFO_L && CHAR_BIT == 8 && HAVE_ICONV
+
+ return str;
+}
+} // namespace __format
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
new file mode 100644
@@ -0,0 +1,47 @@
+// { dg-do run { target c++23 } }
+// { dg-require-namedlocale "ru_UA.koi8u" }
+// { dg-require-namedlocale "es_ES.ISO8859-1" }
+// { dg-require-namedlocale "fr_FR.ISO8859-1" }
+// { dg-require-effective-target cxx11_abi }
+
+// P2419R2
+// Clarify handling of encodings in localized formatting of chrono types
+
+// Localized date-time strings such as "février" should be converted to UTF-8
+// if the locale uses a different encoding.
+
+#include <chrono>
+#include <format>
+#include <testsuite_hooks.h>
+
+void
+test_ru()
+{
+ std::locale loc("ru_UA.koi8u");
+ auto s = std::format(loc, "День недели: {:L}", std::chrono::Monday);
+ VERIFY( s == "День недели: Пн" );
+}
+
+void
+test_es()
+{
+ std::locale loc(ISO_8859(1,es_ES));
+ auto s = std::format(loc, "Día de la semana: {:L%A %a}", std::chrono::Wednesday);
+ VERIFY( s == "Día de la semana: miércoles mié" );
+}
+
+void
+test_fr()
+{
+ std::locale loc(ISO_8859(1,fr_FR));
+ auto s = std::format(loc, "Six mois après {0:L%b}, c'est {1:L%B}.",
+ std::chrono::February, std::chrono::August);
+ VERIFY( s == "Six mois après févr., c'est août." );
+}
+
+int main()
+{
+ test_ru();
+ test_es();
+ test_fr();
+}
@@ -215,6 +215,7 @@ check_version(symbol& test, bool added)
known_versions.push_back("GLIBCXX_3.4.31");
known_versions.push_back("GLIBCXX_3.4.32");
known_versions.push_back("GLIBCXX_3.4.33");
+ known_versions.push_back("GLIBCXX_3.4.34");
known_versions.push_back("GLIBCXX_LDBL_3.4.31");
known_versions.push_back("GLIBCXX_IEEE128_3.4.29");
known_versions.push_back("GLIBCXX_IEEE128_3.4.30");