mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-31 15:31:11 +08:00
libstdc++: Fix stream initialization with static library [PR107701]
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.
This commit is contained in:
parent
c5e8c6c193
commit
ec59848074
@ -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
|
||||
|
@ -69,6 +69,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
fake_wostream wclog;
|
||||
#endif
|
||||
|
||||
#include "ios_base_init.h"
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -1,4 +1,4 @@
|
||||
// { dg-do link { target c++11 } }
|
||||
// { dg-do run { target c++11 } }
|
||||
// { dg-require-static-libstdcxx }
|
||||
// { dg-options "-static-libstdc++" }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user