[libcxx] r210188 - Make locales (and transitively, std::endl) work reliably with gcc.

Nico Weber nicolasweber at gmx.de
Wed Jun 4 08:46:56 PDT 2014


Author: nico
Date: Wed Jun  4 10:46:56 2014
New Revision: 210188

URL: http://llvm.org/viewvc/llvm-project?rev=210188&view=rev
Log:
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.

Modified:
    libcxx/trunk/include/__config
    libcxx/trunk/include/bitset

Modified: libcxx/trunk/include/__config
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=210188&r1=210187&r2=210188&view=diff
==============================================================================
--- libcxx/trunk/include/__config (original)
+++ libcxx/trunk/include/__config Wed Jun  4 10:46:56 2014
@@ -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)

Modified: libcxx/trunk/include/bitset
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/bitset?rev=210188&r1=210187&r2=210188&view=diff
==============================================================================
--- libcxx/trunk/include/bitset (original)
+++ libcxx/trunk/include/bitset Wed Jun  4 10:46:56 2014
@@ -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





More information about the cfe-commits mailing list