Make locales (and transitively, std::endl) work reliably with gcc.
authorNico Weber <nicolasweber@gmx.de>
Wed, 4 Jun 2014 15:46:56 +0000 (15:46 +0000)
committerNico Weber <nicolasweber@gmx.de>
Wed, 4 Jun 2014 15:46:56 +0000 (15:46 +0000)
commit1d1b46cdf71bec1d95ca8a4665990972bd34bfc7
tree6fd7df1fd1ccdb194110360a7f7ef3b90e65bbc8
parent0811e7140260af0da2bbbadf9c8c51011ee78949
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
libcxx/include/bitset