Speculative fix for std stream destruction order on Windows.

The MSVC CRT uses TLS storage to implement per-thread locales.
This storage gets freed during program termination, and if we attempt
to do any io operations (like flushing the std streams) after this occurs
the program may abort.

This patch is a speculative fix for that issue.

The fix tries forcing the initialization of the locale TLS before
initializing the std streams. This should mean that the TLS is freed
after we destroy the streams.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@361348 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/src/iostream.cpp b/src/iostream.cpp
index 9b8d1fa..0a5d6e8 100644
--- a/src/iostream.cpp
+++ b/src/iostream.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "__std_stream"
+#include "__locale"
 #include "string"
 #include "new"
 
@@ -78,8 +79,28 @@
 
 _LIBCPP_HIDDEN ios_base::Init __start_std_streams;
 
+// On Windows the TLS storage for locales needs to be initialized before we create
+// the standard streams, otherwise it may not be alive during program termination
+// when we flush the streams.
+static void force_locale_initialization() {
+#if defined(_LIBCPP_MSVCRT_LIKE)
+  static bool once = []() {
+    auto loc = newlocale(LC_ALL_MASK, "C", 0);
+    {
+        __libcpp_locale_guard g(loc); // forces initialization of locale TLS
+        ((void)g);
+    }
+    freelocale(loc);
+    return true;
+  }();
+  ((void)once);
+#endif
+}
+
 ios_base::Init::Init()
 {
+    force_locale_initialization();
+
 #ifndef _LIBCPP_HAS_NO_STDIN
     istream* cin_ptr  = ::new(cin)  istream(::new(__cin)  __stdinbuf <char>(stdin, &mb_cin));
     wistream* wcin_ptr  = ::new(wcin)  wistream(::new(__wcin)  __stdinbuf <wchar_t>(stdin, &mb_wcin));