[libc++ patch] Make locales (and transitively, std::endl) work reliably with gcc
Nico Weber
thakis at chromium.org
Fri May 30 07:04:39 PDT 2014
Hi,
on trunk, libc++ 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, the attached patch lets _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.)
Once _LIBCPP_CONSTEXPR is available, bitset fails to compile since gcc
doesn't define __SIZE_WIDTH__, so switch bitset to use __SIZEOF_SIZE_T__
which both clang and gcc define.
Pair-programmed/debugged with Dana Jansens.
Nico
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140530/c931b350/attachment.html>
-------------- next part --------------
Index: include/__config
===================================================================
--- include/__config (revision 209887)
+++ include/__config (working copy)
@@ -368,7 +368,14 @@
#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)
Index: include/bitset
===================================================================
--- include/bitset (revision 209887)
+++ include/bitset (working copy)
@@ -249,9 +249,9 @@
_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