Skip to content
Snippets Groups Projects
Commit 61bf34d1 authored by Jonathan Wakely's avatar Jonathan Wakely
Browse files

libstdc++: Fix iostream init for Clang on darwin [PR110432]


The __has_attribute(init_priority) check in <iostream> is true for Clang
on darwin, which means that user code including <iostream> thinks the
library will initialize the global streams. However, when libstdc++ is
built by GCC on darwin, the __has_attribute(init_priority) check is
false, which means that the library thinks that user code will do the
initialization when <iostream> is included. This means that the
initialization is never done.

Add an autoconf check so that the header and the library both make their
decision based on the static properties of GCC at build time, with a
consistent outcome.

As a belt and braces check, also do the initialization in <iostream> if
the compiler including that header doesn't support the attribute (even
if the library also containers the initialization). This might result in
redundant initialization done in <iostream>, but ensures the
initialization happens somewhere if there's any doubt about the
attribute working correctly due to missing linker support.

libstdc++-v3/ChangeLog:

	PR libstdc++/110432
	* acinclude.m4 (GLIBCXX_CHECK_INIT_PRIORITY): New.
	* config.h.in: Regenerate.
	* configure: Regenerate.
	* configure.ac: Use GLIBCXX_CHECK_INIT_PRIORITY.
	* include/std/iostream: Use new autoconf macro as well as
	__has_attribute.
	* src/c++98/ios_base_init.h: Use new autoconf macro instead of
	__has_attribute.

Reviewed-by: default avatarPatrick Palka <ppalka@redhat.com>
(cherry picked from commit fe2651af)
parent 33a84d43
No related branches found
No related tags found
No related merge requests found
......@@ -5290,6 +5290,33 @@ AC_DEFUN([GLIBCXX_CHECK_ALIGNAS_CACHELINE], [
AC_LANG_RESTORE
])
dnl
dnl Check whether iostream initialization should be done in the library,
dnl using the init_priority attribute.
dnl
dnl Defines:
dnl _GLIBCXX_USE_INIT_PRIORITY_ATTRIBUTE if GCC supports the init_priority
dnl attribute for the target.
dnl
AC_DEFUN([GLIBCXX_CHECK_INIT_PRIORITY], [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_MSG_CHECKING([whether init_priority attribute is supported])
AC_TRY_COMPILE(, [
#if ! __has_attribute(init_priority)
#error init_priority not supported
#endif
], [ac_init_priority=yes], [ac_init_priority=no])
if test "$ac_init_priority" = yes; then
AC_DEFINE_UNQUOTED(_GLIBCXX_USE_INIT_PRIORITY_ATTRIBUTE, 1,
[Define if init_priority should be used for iostream initialization.])
fi
AC_MSG_RESULT($ac_init_priority)
AC_LANG_RESTORE
])
# Macros from the top-level gcc directory.
m4_include([../config/gc++filt.m4])
m4_include([../config/tls.m4])
......
......@@ -958,6 +958,9 @@
/* Define if get_nprocs is available in <sys/sysinfo.h>. */
#undef _GLIBCXX_USE_GET_NPROCS
/* Define if init_priority should be used for iostream initialization. */
#undef _GLIBCXX_USE_INIT_PRIORITY_ATTRIBUTE
/* Define if LFS support is available. */
#undef _GLIBCXX_USE_LFS
......
......@@ -71732,6 +71732,57 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
# For using init_priority in ios_init.cc
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether init_priority attribute is supported" >&5
$as_echo_n "checking whether init_priority attribute is supported... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
#if ! __has_attribute(init_priority)
#error init_priority not supported
#endif
;
return 0;
}
_ACEOF
if ac_fn_cxx_try_compile "$LINENO"; then :
ac_init_priority=yes
else
ac_init_priority=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
if test "$ac_init_priority" = yes; then
cat >>confdefs.h <<_ACEOF
#define _GLIBCXX_USE_INIT_PRIORITY_ATTRIBUTE 1
_ACEOF
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_init_priority" >&5
$as_echo "$ac_init_priority" >&6; }
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
# Define documentation rules conditionally.
 
# See if makeinfo has been installed and is modern enough
......@@ -541,6 +541,9 @@ GLIBCXX_ZONEINFO_DIR
# For src/c++11/shared_ptr.cc alignment.
GLIBCXX_CHECK_ALIGNAS_CACHELINE
# For using init_priority in ios_init.cc
GLIBCXX_CHECK_INIT_PRIORITY
# Define documentation rules conditionally.
# See if makeinfo has been installed and is modern enough
......
......@@ -75,7 +75,8 @@ _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/globals_io.cc).
#if !__has_attribute(__init_priority__)
#if !(_GLIBCXX_USE_INIT_PRIORITY_ATTRIBUTE \
&& __has_attribute(__init_priority__))
static ios_base::Init __ioinit;
#elif defined(_GLIBCXX_SYMVER_GNU)
__extension__ __asm (".globl _ZSt21ios_base_library_initv");
......
......@@ -8,6 +8,6 @@
// 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)
#if _GLIBCXX_USE_INIT_PRIORITY_ATTRIBUTE
static ios_base::Init __ioinit __attribute__((init_priority(90)));
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment