diff mbox series

[v3] Implement LWG 2221, No formatted output operator for nullptr

Message ID CAFk2RUa_FkNpgnu3nJw4ZdNnuDx4+tmcM045vuXFhM3pivLp5g@mail.gmail.com
State New
Headers show
Series [v3] Implement LWG 2221, No formatted output operator for nullptr | expand

Commit Message

Ville Voutilainen Dec. 3, 2017, 9:08 p.m. UTC
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.

Comments

Jonathan Wakely Dec. 4, 2017, 11:04 p.m. UTC | #1
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.
Jonathan Wakely Jan. 10, 2019, 1:15 p.m. UTC | #2
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;
+}
Rainer Orth Jan. 10, 2019, 9:27 p.m. UTC | #3
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
Jonathan Wakely Jan. 11, 2019, 12:01 a.m. UTC | #4
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*;
Rainer Orth Jan. 11, 2019, 9:07 a.m. UTC | #5
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
Jonathan Wakely Jan. 11, 2019, 11 a.m. UTC | #6
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 mbox series

Patch

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;
+}