aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2022-11-06 11:16:00 -0500
committerPatrick Palka <ppalka@redhat.com>2022-11-06 11:16:00 -0500
commit4e4e3ffd10f53ef71696bc728ab40258751a2df4 (patch)
tree3a161134d60201a9391d4a0095c12ca8c4c6a6e7
parentd0a492faa6478c99d325fa4a7ed2e5633cef7529 (diff)
downloadgcc-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/iostream4
-rw-r--r--libstdc++-v3/src/c++98/ios_base_init.h12
-rw-r--r--libstdc++-v3/src/c++98/ios_init.cc2
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)