Message ID | CAFk2RUa_FkNpgnu3nJw4ZdNnuDx4+tmcM045vuXFhM3pivLp5g@mail.gmail.com |
---|---|
State | New |
Headers | show |
Series | [v3] Implement LWG 2221, No formatted output operator for nullptr | expand |
On 03/12/17 23:08 +0200, Ville Voutilainen wrote: >Tested on Linux-x64. > >2017-11-14 Ville Voutilainen <ville.voutilainen@gmail.com> > > Implement LWG 2221 > * include/std/ostream (operator<<(nullptr_t)): New. > * testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc: New. >diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream >index f7cab03..18011bc 100644 >--- a/libstdc++-v3/include/std/ostream >+++ b/libstdc++-v3/include/std/ostream >@@ -245,6 +245,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > operator<<(const void* __p) > { return _M_insert(__p); } > >+#if __cplusplus > 201402L >+ __ostream_type& >+ operator<<(nullptr_t) >+ { return *this << "nullptr"; } >+#endif As discussed on IRC, this requires a new symbol to be exported for the std::ostream and std::wostream explicit instantiations, or the new test will fail to link at -O0. That should wait for stage 1.
On 04/12/17 23:04 +0000, Jonathan Wakely wrote: >On 03/12/17 23:08 +0200, Ville Voutilainen wrote: >>Tested on Linux-x64. >> >>2017-11-14 Ville Voutilainen <ville.voutilainen@gmail.com> >> >> Implement LWG 2221 >> * include/std/ostream (operator<<(nullptr_t)): New. >> * testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc: New. > >>diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream >>index f7cab03..18011bc 100644 >>--- a/libstdc++-v3/include/std/ostream >>+++ b/libstdc++-v3/include/std/ostream >>@@ -245,6 +245,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >> operator<<(const void* __p) >> { return _M_insert(__p); } >> >>+#if __cplusplus > 201402L >>+ __ostream_type& >>+ operator<<(nullptr_t) >>+ { return *this << "nullptr"; } >>+#endif > >As discussed on IRC, this requires a new symbol to be exported for the >std::ostream and std::wostream explicit instantiations, or the new >test will fail to link at -O0. > >That should wait for stage 1. > This patch for a C++17 feature (posted over a year ago) should have gone in during stage 1. I've taken care of the symbol exports that were missing from the original patch. Tested x86_64-linux, committed to trunk. commit 81a14252318562c32e5a0c466a39568e741ab6e6 Author: Jonathan Wakely <jwakely@redhat.com> Date: Thu Jan 10 11:44:19 2019 +0000 Implement LWG 2221: formatted output operator for nullptr 2019-01-10 Ville Voutilainen <ville.voutilainen@gmail.com> Jonathan Wakely <jwakely@redhat.com> Implement LWG 2221 * config/abi/pre/gnu.ver (GLIBCXX_3.4): Tighten patterns. (GLIBCXX_3.4.26): Add new exports. * include/Makefile.am: Add ostream-inst.cc. Move string-inst.cc to correct list of sources. * include/Makefile.in: Regenerate. * include/std/ostream (operator<<(nullptr_t)): New member function. * src/c++17/ostream-inst.cc: New file. * testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc: New test. diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 92af1aec7b4..788c2e0303c 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -495,7 +495,7 @@ GLIBCXX_3.4 { _ZNSo8_M_writeEPKc[ilx]; _ZNSo3put*; _ZNSo[5-9][a-z]*; - _ZNSolsE*[^g]; + _ZNSolsE*[^Dg]; # std::basic_ostream<wchar_t> _ZNSt13basic_ostreamIwSt11char_traitsIwEEC[12]Ev; @@ -509,7 +509,7 @@ GLIBCXX_3.4 { _ZNSt13basic_ostreamIwSt11char_traitsIwEE5writeEPKw*; _ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentry*; _ZNSt13basic_ostreamIwSt11char_traitsIwEE8_M_writeEPKw[ilx]; - _ZNSt13basic_ostreamIwSt11char_traitsIwEElsE*[^g]; + _ZNSt13basic_ostreamIwSt11char_traitsIwEElsE*[^Dg]; # std::ostream operators and inserters _ZSt4end[ls]I[cw]St11char_traitsI[cw]EERSt13basic_ostream*; @@ -2223,6 +2223,10 @@ GLIBCXX_3.4.26 { _ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSEOS1_; _ZNSt10filesystem7__cxx1128recursive_directory_iteratorppEv; + # basic_ostream::operator<<(nullptr_t) + _ZNSolsEDn; + _ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn; + } GLIBCXX_3.4.25; # Symbols in the support library (libsupc++) have their own tag. diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream index 50c99b25d58..2541d978886 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -245,6 +245,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator<<(const void* __p) { return _M_insert(__p); } +#if __cplusplus >= 201703L + __ostream_type& + operator<<(nullptr_t) + { return *this << "nullptr"; } +#endif + /** * @brief Extracting from another streambuf. * @param __sb A pointer to a streambuf diff --git a/libstdc++-v3/src/c++17/Makefile.am b/libstdc++-v3/src/c++17/Makefile.am index 4200f7f8259..1a00770081e 100644 --- a/libstdc++-v3/src/c++17/Makefile.am +++ b/libstdc++-v3/src/c++17/Makefile.am @@ -41,6 +41,8 @@ endif if ENABLE_EXTERN_TEMPLATE # XTEMPLATE_FLAGS = -fno-implicit-templates inst_sources = \ + ostream-inst.cc \ + string-inst.cc \ $(extra_string_inst_sources) else # XTEMPLATE_FLAGS = @@ -52,7 +54,6 @@ sources = \ fs_ops.cc \ fs_path.cc \ memory_resource.cc \ - string-inst.cc \ $(extra_fs_sources) vpath % $(top_srcdir)/src/c++17 diff --git a/libstdc++-v3/src/c++17/ostream-inst.cc b/libstdc++-v3/src/c++17/ostream-inst.cc new file mode 100644 index 00000000000..b2fbafcef91 --- /dev/null +++ b/libstdc++-v3/src/c++17/ostream-inst.cc @@ -0,0 +1,42 @@ +// std::ostream instantiations for C++17 -*- C++ -*- + +// Copyright (C) 2019 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 +// <http://www.gnu.org/licenses/>. + +// +// ISO C++ 14882:2017 28 Input/output library +// + +#include <ostream> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +template basic_ostream<char>& basic_ostream<char>::operator<<(nullptr_t); + +#ifdef _GLIBCXX_USE_WCHAR_T +template basic_ostream<wchar_t>& basic_ostream<wchar_t>::operator<<(nullptr_t); +#endif + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc new file mode 100644 index 00000000000..b4ff52b7d2c --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc @@ -0,0 +1,9 @@ +// { dg-options "-std=gnu++17 -fno-inline" } +// { dg-do link } + +#include <iostream> + +int main() +{ + std::cout << nullptr << std::endl; +}
Hi Jonathan, > On 04/12/17 23:04 +0000, Jonathan Wakely wrote: >>On 03/12/17 23:08 +0200, Ville Voutilainen wrote: >>>Tested on Linux-x64. >>> >>>2017-11-14 Ville Voutilainen <ville.voutilainen@gmail.com> >>> >>> Implement LWG 2221 >>> * include/std/ostream (operator<<(nullptr_t)): New. >>> * testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc: New. >> >>>diff --git a/libstdc++-v3/include/std/ostream >>> b/libstdc++-v3/include/std/ostream >>>index f7cab03..18011bc 100644 >>>--- a/libstdc++-v3/include/std/ostream >>>+++ b/libstdc++-v3/include/std/ostream >>>@@ -245,6 +245,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >>> operator<<(const void* __p) >>> { return _M_insert(__p); } >>> >>>+#if __cplusplus > 201402L >>>+ __ostream_type& >>>+ operator<<(nullptr_t) >>>+ { return *this << "nullptr"; } >>>+#endif >> >>As discussed on IRC, this requires a new symbol to be exported for the >>std::ostream and std::wostream explicit instantiations, or the new >>test will fail to link at -O0. >> >>That should wait for stage 1. >> > > This patch for a C++17 feature (posted over a year ago) should have > gone in during stage 1. I've taken care of the symbol exports that > were missing from the original patch. > > Tested x86_64-linux, committed to trunk. this patch broke Solaris bootstrap: ld: fatal: libstdc++-symbols.ver-sun: 7117: symbol 'std::basic_ostream<char, std::char_traits<char> >::operator<<(decltype(nullptr))': symbol version conflict ld: fatal: libstdc++-symbols.ver-sun: 7119: symbol 'std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::operator<<(decltype(nullptr))': symbol version conflict ld: fatal: libstdc++-symbols.ver-sun: 7117: symbol '_ZNSolsEDn': symbol version conflict ld: fatal: libstdc++-symbols.ver-sun: 7119: symbol '_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn': symbol version conflict Again, there were two matches for those two symbols: GLIBCXX_3.4 ##_ZNSolsE*[^Dg] (glob) _ZNSolsEDn; GLIBCXX_3.4.26 ##_ZNSolsEDn (glob) _ZNSolsEDn; GLIBCXX_3.4 ##_ZNSt13basic_ostreamIwSt11char_traitsIwEElsE*[^Dg] (glob) _ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn; GLIBCXX_3.4.26 ##_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn (glob) _ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn; ISTM that the patterns were backwards. The following patch fixes this and allowed i386-pc-solaris2.11 bootstrap to complete without regressions relative to the last successful one. Ok for mainline? Rainer
On 10/01/19 22:27 +0100, Rainer Orth wrote: >Hi Jonathan, > >> On 04/12/17 23:04 +0000, Jonathan Wakely wrote: >>>On 03/12/17 23:08 +0200, Ville Voutilainen wrote: >>>>Tested on Linux-x64. >>>> >>>>2017-11-14 Ville Voutilainen <ville.voutilainen@gmail.com> >>>> >>>> Implement LWG 2221 >>>> * include/std/ostream (operator<<(nullptr_t)): New. >>>> * testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc: New. >>> >>>>diff --git a/libstdc++-v3/include/std/ostream >>>> b/libstdc++-v3/include/std/ostream >>>>index f7cab03..18011bc 100644 >>>>--- a/libstdc++-v3/include/std/ostream >>>>+++ b/libstdc++-v3/include/std/ostream >>>>@@ -245,6 +245,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >>>> operator<<(const void* __p) >>>> { return _M_insert(__p); } >>>> >>>>+#if __cplusplus > 201402L >>>>+ __ostream_type& >>>>+ operator<<(nullptr_t) >>>>+ { return *this << "nullptr"; } >>>>+#endif >>> >>>As discussed on IRC, this requires a new symbol to be exported for the >>>std::ostream and std::wostream explicit instantiations, or the new >>>test will fail to link at -O0. >>> >>>That should wait for stage 1. >>> >> >> This patch for a C++17 feature (posted over a year ago) should have >> gone in during stage 1. I've taken care of the symbol exports that >> were missing from the original patch. >> >> Tested x86_64-linux, committed to trunk. > >this patch broke Solaris bootstrap: > >ld: fatal: libstdc++-symbols.ver-sun: 7117: symbol 'std::basic_ostream<char, std::char_traits<char> >::operator<<(decltype(nullptr))': symbol version conflict >ld: fatal: libstdc++-symbols.ver-sun: 7119: symbol 'std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::operator<<(decltype(nullptr))': symbol version conflict > >ld: fatal: libstdc++-symbols.ver-sun: 7117: symbol '_ZNSolsEDn': symbol version conflict >ld: fatal: libstdc++-symbols.ver-sun: 7119: symbol '_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn': symbol version conflict > >Again, there were two matches for those two symbols: > > GLIBCXX_3.4 > ##_ZNSolsE*[^Dg] (glob) > _ZNSolsEDn; > GLIBCXX_3.4.26 > ##_ZNSolsEDn (glob) > _ZNSolsEDn; > > GLIBCXX_3.4 > ##_ZNSt13basic_ostreamIwSt11char_traitsIwEElsE*[^Dg] (glob) > _ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn; > GLIBCXX_3.4.26 > ##_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn (glob) > _ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn; > >ISTM that the patterns were backwards. The following patch fixes this >and allowed i386-pc-solaris2.11 bootstrap to complete without >regressions relative to the last successful one. I think what I should have done is change [^g] to [^gn]. That preserves the original behaviour (don't match the ppc64 long double symbols) but also excludes the new symbols, which end in 'n'. Maybe the attached patch would be better though. It matches every basic_ostream::operator<<(T) for any scalar T except 'g', and adds a second pattern to match basic_ostream::operator<<(T*) for various T. But neither of those matches the new operator<<(nullptr_t) overload. FWIW I did run my symbol checker script, but it gets lots of false positives because it doesn't understand the #if preprocessor conditions, so it sees lots of false positive duplicates. I need to make it smarter for it to be useful here. diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 788c2e0303c..d3431d2c78e 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -495,7 +495,8 @@ GLIBCXX_3.4 { _ZNSo8_M_writeEPKc[ilx]; _ZNSo3put*; _ZNSo[5-9][a-z]*; - _ZNSolsE*[^Dg]; + _ZNSolsE[^g]; + _ZNSolsEP*; # std::basic_ostream<wchar_t> _ZNSt13basic_ostreamIwSt11char_traitsIwEEC[12]Ev; @@ -509,7 +510,8 @@ GLIBCXX_3.4 { _ZNSt13basic_ostreamIwSt11char_traitsIwEE5writeEPKw*; _ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentry*; _ZNSt13basic_ostreamIwSt11char_traitsIwEE8_M_writeEPKw[ilx]; - _ZNSt13basic_ostreamIwSt11char_traitsIwEElsE*[^Dg]; + _ZNSt13basic_ostreamIwSt11char_traitsIwEElsE[^g]; + _ZNSt13basic_ostreamIwSt11char_traitsIwEElsEP*; # std::ostream operators and inserters _ZSt4end[ls]I[cw]St11char_traitsI[cw]EERSt13basic_ostream*;
Hi Jonathan, >>this patch broke Solaris bootstrap: >> >>ld: fatal: libstdc++-symbols.ver-sun: 7117: symbol 'std::basic_ostream<char, std::char_traits<char> >::operator<<(decltype(nullptr))': symbol version conflict >>ld: fatal: libstdc++-symbols.ver-sun: 7119: symbol 'std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::operator<<(decltype(nullptr))': symbol version conflict >> >>ld: fatal: libstdc++-symbols.ver-sun: 7117: symbol '_ZNSolsEDn': symbol version conflict >>ld: fatal: libstdc++-symbols.ver-sun: 7119: symbol '_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn': symbol version conflict >> >>Again, there were two matches for those two symbols: >> >> GLIBCXX_3.4 >> ##_ZNSolsE*[^Dg] (glob) >> _ZNSolsEDn; >> GLIBCXX_3.4.26 >> ##_ZNSolsEDn (glob) >> _ZNSolsEDn; >> >> GLIBCXX_3.4 >> ##_ZNSt13basic_ostreamIwSt11char_traitsIwEElsE*[^Dg] (glob) >> _ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn; >> GLIBCXX_3.4.26 >> ##_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn (glob) >> _ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn; >> >>ISTM that the patterns were backwards. The following patch fixes this >>and allowed i386-pc-solaris2.11 bootstrap to complete without >>regressions relative to the last successful one. > > I think what I should have done is change [^g] to [^gn]. That > preserves the original behaviour (don't match the ppc64 long double > symbols) but also excludes the new symbols, which end in 'n'. > > Maybe the attached patch would be better though. It matches every > basic_ostream::operator<<(T) for any scalar T except 'g', and adds a > second pattern to match basic_ostream::operator<<(T*) for various T. > But neither of those matches the new operator<<(nullptr_t) overload. it allowed me to link libstdc++.so, too. For my patch I'd only been going from the ld errors and the matching patterns in the generated libstdc++.map-sun, not knowing the background here. > FWIW I did run my symbol checker script, but it gets lots of false > positives because it doesn't understand the #if preprocessor > conditions, so it sees lots of false positive duplicates. I need to > make it smarter for it to be useful here. Indeed: the variation possible here can be a total PITA ;-) Thanks. Rainer
On 11/01/19 10:07 +0100, Rainer Orth wrote: >Hi Jonathan, > >>>this patch broke Solaris bootstrap: >>> >>>ld: fatal: libstdc++-symbols.ver-sun: 7117: symbol 'std::basic_ostream<char, std::char_traits<char> >::operator<<(decltype(nullptr))': symbol version conflict >>>ld: fatal: libstdc++-symbols.ver-sun: 7119: symbol 'std::basic_ostream<wchar_t, std::char_traits<wchar_t> >::operator<<(decltype(nullptr))': symbol version conflict >>> >>>ld: fatal: libstdc++-symbols.ver-sun: 7117: symbol '_ZNSolsEDn': symbol version conflict >>>ld: fatal: libstdc++-symbols.ver-sun: 7119: symbol '_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn': symbol version conflict >>> >>>Again, there were two matches for those two symbols: >>> >>> GLIBCXX_3.4 >>> ##_ZNSolsE*[^Dg] (glob) >>> _ZNSolsEDn; >>> GLIBCXX_3.4.26 >>> ##_ZNSolsEDn (glob) >>> _ZNSolsEDn; >>> >>> GLIBCXX_3.4 >>> ##_ZNSt13basic_ostreamIwSt11char_traitsIwEElsE*[^Dg] (glob) >>> _ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn; >>> GLIBCXX_3.4.26 >>> ##_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn (glob) >>> _ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn; >>> >>>ISTM that the patterns were backwards. The following patch fixes this >>>and allowed i386-pc-solaris2.11 bootstrap to complete without >>>regressions relative to the last successful one. >> >> I think what I should have done is change [^g] to [^gn]. That >> preserves the original behaviour (don't match the ppc64 long double >> symbols) but also excludes the new symbols, which end in 'n'. >> >> Maybe the attached patch would be better though. It matches every >> basic_ostream::operator<<(T) for any scalar T except 'g', and adds a >> second pattern to match basic_ostream::operator<<(T*) for various T. >> But neither of those matches the new operator<<(nullptr_t) overload. > >it allowed me to link libstdc++.so, too. For my patch I'd only been >going from the ld errors and the matching patterns in the generated >libstdc++.map-sun, not knowing the background here. THanks for checking it. I've committed the patch now. >> FWIW I did run my symbol checker script, but it gets lots of false >> positives because it doesn't understand the #if preprocessor >> conditions, so it sees lots of false positive duplicates. I need to >> make it smarter for it to be useful here. > >Indeed: the variation possible here can be a total PITA ;-) I've managed to cobble together a pipeline with sed and cpp that allows me to test the linker script properly. It found some conflicts that still remain but presumably aren't present on Solaris because HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT is not defined. There's one remaining conflict, which https://gcc.gnu.org/PR88125 covers. I'll commit a patch for those shortly.
diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream index f7cab03..18011bc 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -245,6 +245,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator<<(const void* __p) { return _M_insert(__p); } +#if __cplusplus > 201402L + __ostream_type& + operator<<(nullptr_t) + { return *this << "nullptr"; } +#endif + /** * @brief Extracting from another streambuf. * @param __sb A pointer to a streambuf diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc new file mode 100644 index 0000000..1ffacb3 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc @@ -0,0 +1,9 @@ +// { dg-options "-std=gnu++17" } +// { dg-do compile } + +#include <iostream> + +int main() +{ + std::cout << nullptr << std::endl; +}