From 1d1b46cdf71bec1d95ca8a4665990972bd34bfc7 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Wed, 4 Jun 2014 15:46:56 +0000 Subject: [PATCH] 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::id::_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. llvm-svn: 210188 --- libcxx/include/__config | 7 +++++++ libcxx/include/bitset | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__config b/libcxx/include/__config index ce39243..f803c9a 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -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) diff --git a/libcxx/include/bitset b/libcxx/include/bitset index 4cc7dbd..8c278cc 100644 --- a/libcxx/include/bitset +++ b/libcxx/include/bitset @@ -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 -- 2.7.4