]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Fix stream initialization with static library [PR107701]
authorPatrick Palka <ppalka@redhat.com>
Wed, 16 Nov 2022 13:53:51 +0000 (08:53 -0500)
committerPatrick Palka <ppalka@redhat.com>
Wed, 16 Nov 2022 13:53:51 +0000 (08:53 -0500)
When linking with a static library, the linker seems to discard a
constituent .o object (including its global initializers) if nothing
defined in the object is referenced by the program (unless e.g.
--whole-archive is used).  This behavior breaks iostream with static
libstdc++.a (on systems that support init priorities) because we define
the global initializer for the standard stream objects in a separate TU
(ios_init.cc) from the stream object definitions (globals_io.cc).

This patch fixes this by moving the stream initialization object into
the same TU that defines the stream objects, so that any use of the
streams prevents the linker from discarding this global initializer.

PR libstdc++/107701

libstdc++-v3/ChangeLog:

* include/std/iostream (__ioinit): Adjust comment.
* src/c++98/globals_io.cc: Include "io_base_init.h" here
instead of ...
* src/c++98/ios_init.cc: ... here.
* src/c++98/ios_base_init.h (__ioinit): More comments.
* testsuite/17_intro/static.cc: dg-do run instead of just link.

libstdc++-v3/include/std/iostream
libstdc++-v3/src/c++98/globals_io.cc
libstdc++-v3/src/c++98/ios_base_init.h
libstdc++-v3/src/c++98/ios_init.cc
libstdc++-v3/testsuite/17_intro/static.cc

index ff78e1cfb875e81f00f061ca779fd9da1f15a0ad..0c62e9aeb7f3b6e02cf406625cfdfa0d0306c911 100644 (file)
@@ -74,7 +74,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // For construction of filebuffers for cout, cin, cerr, clog et. al.
   // When the init_priority attribute is usable, we do this initialization
-  // in the compiled library instead (src/c++98/ios_init.cc).
+  // in the compiled library instead (src/c++98/globals_io.cc).
 #if !__has_attribute(__init_priority__)
   static ios_base::Init __ioinit;
 #endif
index 04fecb22aeb5db29d193728763299651bb5fe62f..bfd808b5bbdd4121659db2eac46120f61f28fb25 100644 (file)
@@ -69,6 +69,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   fake_wostream wclog;
 #endif
 
+#include "ios_base_init.h"
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
index 1c71038f4a12d11eb5df5f3bc487e3bfe5e28c3d..b600ec3298e45f252a8231a087be911a4aaefc66 100644 (file)
@@ -7,6 +7,7 @@
 // sufficiently early (so that it happens before any other global
 // constructor when statically linking with libstdc++.a), instead of
 // doing so in (each TU that includes) <iostream>.
+// This needs to be done in the same TU that defines the stream objects.
 #if __has_attribute(init_priority)
 static ios_base::Init __ioinit __attribute__((init_priority(90)));
 #endif
index 4016fcab785b4a8901634ef4241fc67d3cc4aef0..1b5132f1c2df1a09411f3a664ba617aaf7bc75f9 100644 (file)
@@ -75,8 +75,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   extern wostream wclog;
 #endif
 
-#include "ios_base_init.h"
-
   ios_base::Init::Init()
   {
     if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, 1) == 0)
index ffa7ecb7077b7eed65fabb8fcc7e1c4195b2d43c..a0d6ed081f8e4eb7a5d73bc3052884e2d463592f 100644 (file)
@@ -1,4 +1,4 @@
-// { dg-do link { target c++11 } }
+// { dg-do run { target c++11 } }
 // { dg-require-static-libstdcxx }
 // { dg-options "-static-libstdc++" }