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.
This commit is contained in:
Patrick Palka
2022-11-06 11:16:00 -05:00
parent d0a492faa6
commit 4e4e3ffd10
3 changed files with 18 additions and 0 deletions
+4
View File
@@ -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
+12
View File
@@ -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
+2
View File
@@ -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)