From 4e4e3ffd10f53ef71696bc728ab40258751a2df4 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Sun, 6 Nov 2022 11:16:00 -0500 Subject: [PATCH] libstdc++: Move stream initialization into compiled library [PR44952] This patch moves the static object for constructing the standard streams out from and into the compiled library on systems that support init priorities. This'll mean 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. --- libstdc++-v3/include/std/iostream | 4 ++++ libstdc++-v3/src/c++98/ios_base_init.h | 12 ++++++++++++ libstdc++-v3/src/c++98/ios_init.cc | 2 ++ 3 files changed, 18 insertions(+) create mode 100644 libstdc++-v3/src/c++98/ios_base_init.h 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 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) . +#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) -- 2.7.4