diff options
author | Patrick Palka <ppalka@redhat.com> | 2022-11-06 11:16:00 -0500 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2022-11-06 11:16:00 -0500 |
commit | 4e4e3ffd10f53ef71696bc728ab40258751a2df4 (patch) | |
tree | 3a161134d60201a9391d4a0095c12ca8c4c6a6e7 | |
parent | d0a492faa6478c99d325fa4a7ed2e5633cef7529 (diff) | |
download | gcc-4e4e3ffd10f53ef71696bc728ab40258751a2df4.zip gcc-4e4e3ffd10f53ef71696bc728ab40258751a2df4.tar.gz gcc-4e4e3ffd10f53ef71696bc728ab40258751a2df4.tar.bz2 |
libstdc++: Move stream initialization into compiled library [PR44952]
This patch moves the static object for constructing the standard streams
out from <iostream> and into the compiled library on systems that support
init priorities. This'll mean <iostream> no longer introduces a separate
global constructor in each TU that includes it.
We can do this only if the init_priority attribute is supported because
we need a way to ensure the stream initialization runs first before any
user global initializer, particularly when linking with a static
libstdc++.a.
PR libstdc++/44952
PR libstdc++/39796
PR libstdc++/98108
libstdc++-v3/ChangeLog:
* include/std/iostream (__ioinit): No longer define here if
the init_priority attribute is usable.
* src/c++98/ios_init.cc (__ioinit): Define here instead if
init_priority is usable, via ...
* src/c++98/ios_base_init.h: ... this new file.
-rw-r--r-- | libstdc++-v3/include/std/iostream | 4 | ||||
-rw-r--r-- | libstdc++-v3/src/c++98/ios_base_init.h | 12 | ||||
-rw-r--r-- | libstdc++-v3/src/c++98/ios_init.cc | 2 |
3 files changed, 18 insertions, 0 deletions
diff --git a/libstdc++-v3/include/std/iostream b/libstdc++-v3/include/std/iostream index 70318a4..ff78e1c 100644 --- a/libstdc++-v3/include/std/iostream +++ b/libstdc++-v3/include/std/iostream @@ -73,7 +73,11 @@ _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). +#if !__has_attribute(__init_priority__) static ios_base::Init __ioinit; +#endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/c++98/ios_base_init.h b/libstdc++-v3/src/c++98/ios_base_init.h new file mode 100644 index 0000000..1c71038 --- /dev/null +++ b/libstdc++-v3/src/c++98/ios_base_init.h @@ -0,0 +1,12 @@ +// This is only in a header so we can use the system_header pragma, +// to suppress the warning caused by using a reserved init_priority. +#pragma GCC system_header + +// If the target supports init priorities, set up a static object in the +// compiled library to perform the <iostream> initialization once and +// 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>. +#if __has_attribute(init_priority) +static ios_base::Init __ioinit __attribute__((init_priority(90))); +#endif diff --git a/libstdc++-v3/src/c++98/ios_init.cc b/libstdc++-v3/src/c++98/ios_init.cc index 1b5132f..4016fca 100644 --- a/libstdc++-v3/src/c++98/ios_init.cc +++ b/libstdc++-v3/src/c++98/ios_init.cc @@ -75,6 +75,8 @@ _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) |