Make locales (and transitively, std::endl) work reliably with gcc.
libc++ currently relies on undefined initialization order of global initializers when using gcc: 1. __start_std_streams in iostream.cpp calls locale:🆔:_init, which assigns an id to each locale::facet in an initializer 2. Every facet has a static locale::id id, whose constructor sets the facet's id to 0 If 2 runs after 1, it clobbers the facet's assigned consecutive id, causing exceptions to be thrown when e.g. running code like "cout << endl". To fix this, let _LIBCPP_CONSTEXPR evaluate to "constexpr" instead of nothing with gcc. locale::id's constructor is marked _LIBCPP_CONSTEXPR, which ensures that it won't get an initializer that could potentially run after the iostream.cpp initializer. (This remains broken when building with msvc.) Also switch constexpr-specific code in bitset to use __SIZEOF_SIZE_T__ instead of __SIZE_WIDTH__, because gcc doesn't define the latter. Pair-programmed/debugged with Dana Jansens. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@210188 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5a54699578
commit
0211e86a5e
@ -368,7 +368,14 @@ namespace std {
|
||||
#endif
|
||||
|
||||
#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
|
||||
|
||||
// constexpr was added to GCC in 4.6.
|
||||
#if _GNUC_VER < 406
|
||||
#define _LIBCPP_HAS_NO_CONSTEXPR
|
||||
// Can only use constexpr in c++11 mode.
|
||||
#elif !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L
|
||||
#define _LIBCPP_HAS_NO_CONSTEXPR
|
||||
#endif
|
||||
|
||||
#define _NOEXCEPT throw()
|
||||
#define _NOEXCEPT_(x)
|
||||
|
@ -249,9 +249,9 @@ inline _LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR
|
||||
__bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
|
||||
#ifndef _LIBCPP_HAS_NO_CONSTEXPR
|
||||
#if __SIZE_WIDTH__ == 64
|
||||
#if __SIZEOF_SIZE_T__ == 8
|
||||
: __first_{__v}
|
||||
#elif __SIZE_WIDTH__ == 32
|
||||
#elif __SIZEOF_SIZE_T__ == 4
|
||||
: __first_{__v, __v >> __bits_per_word}
|
||||
#else
|
||||
#error This constructor has not been ported to this platform
|
||||
|
Loading…
x
Reference in New Issue
Block a user