[libc++] Avoid <memory> include in locale_win32.h
authorShoaib Meenai <smeenai@fb.com>
Thu, 15 Sep 2016 18:36:13 +0000 (18:36 +0000)
committerShoaib Meenai <smeenai@fb.com>
Thu, 15 Sep 2016 18:36:13 +0000 (18:36 +0000)
When `_LIBCPP_NO_EXCEPTIONS` is defined, we end up with compile errors
when targeting MSVCRT:

* Code includes `<new>`
* `<new>` includes `<cstdlib>` in order to get `abort`
* `<cstdlib>` includes `<stdlib.h>`, _before_ the `using ::abort`
* `<stdlib.h>` includes `locale_win32.h`
* `locale_win32.h` includes `<memory>`
* `<memory>` includes `<stdexcept>`
* `<stdexcept>` includes `<cstdlib` for `abort`, but that inclusion gets
  (correctly) ignored because of header guards
* `<stdexcept>` references `_VSTD::abort`, which isn't declared

The easiest solution is to make `locale_win32.h` not include `<memory>`,
by removing the use of `unique_ptr` and manually restoring the locale
instead.

Differential Revision: https://reviews.llvm.org/D24374

llvm-svn: 281641

libcxx/include/support/win32/locale_win32.h
libcxx/src/support/win32/locale_win32.cpp

index 7f3710e..4cb6d56 100644 (file)
@@ -17,7 +17,6 @@ extern "C" unsigned short  __declspec(dllimport) _ctype[];
 #include "support/win32/support.h"
 #include "support/win32/locale_mgmt_win32.h"
 #include <stdio.h>
-#include <memory>
 
 lconv *localeconv_l( locale_t loc );
 size_t mbrlen_l( const char *__restrict s, size_t n,
@@ -34,13 +33,10 @@ size_t wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src,
                      size_t nwc, size_t len, mbstate_t *__restrict ps, locale_t loc);
 wint_t btowc_l( int c, locale_t loc );
 int wctob_l( wint_t c, locale_t loc );
-typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
-typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;
 inline _LIBCPP_ALWAYS_INLINE
 decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l )
 {
-  __locale_raii __current( uselocale(__l), uselocale );
-  return MB_CUR_MAX;
+  return ___mb_cur_max_l_func(__l);
 }
 
 // the *_l functions are prefixed on Windows, only available for msvcr80+, VS2005+
index 5a43743..7300451 100644 (file)
 
 #include <locale>
 #include <cstdarg> // va_start, va_end
+#include <memory>
+#include <type_traits>
+
+typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
+typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;
 
 // FIXME: base currently unused. Needs manual work to construct the new locale
 locale_t newlocale( int mask, const char * locale, locale_t /*base*/ )