diff options
Diffstat (limited to 'contrib/libc++/src')
| -rw-r--r-- | contrib/libc++/src/chrono.cpp | 66 | ||||
| -rw-r--r-- | contrib/libc++/src/config_elast.h | 36 | ||||
| -rw-r--r-- | contrib/libc++/src/debug.cpp | 2 | ||||
| -rw-r--r-- | contrib/libc++/src/exception.cpp | 32 | ||||
| -rw-r--r-- | contrib/libc++/src/future.cpp | 5 | ||||
| -rw-r--r-- | contrib/libc++/src/ios.cpp | 14 | ||||
| -rw-r--r-- | contrib/libc++/src/iostream.cpp | 68 | ||||
| -rw-r--r-- | contrib/libc++/src/locale.cpp | 206 | ||||
| -rw-r--r-- | contrib/libc++/src/memory.cpp | 17 | ||||
| -rw-r--r-- | contrib/libc++/src/mutex.cpp | 10 | ||||
| -rw-r--r-- | contrib/libc++/src/new.cpp | 16 | ||||
| -rw-r--r-- | contrib/libc++/src/random.cpp | 96 | ||||
| -rw-r--r-- | contrib/libc++/src/shared_mutex.cpp | 25 | ||||
| -rw-r--r-- | contrib/libc++/src/string.cpp | 2 | ||||
| -rw-r--r-- | contrib/libc++/src/support/atomic_support.h | 142 | ||||
| -rw-r--r-- | contrib/libc++/src/system_error.cpp | 9 | ||||
| -rw-r--r-- | contrib/libc++/src/thread.cpp | 4 | 
17 files changed, 562 insertions, 188 deletions
diff --git a/contrib/libc++/src/chrono.cpp b/contrib/libc++/src/chrono.cpp index 456941144e01..62149fbf420c 100644 --- a/contrib/libc++/src/chrono.cpp +++ b/contrib/libc++/src/chrono.cpp @@ -8,14 +8,21 @@  //===----------------------------------------------------------------------===//  #include "chrono" -#include <sys/time.h>        //for gettimeofday and timeval -#ifdef __APPLE__ +#include "cerrno"        // errno +#include "system_error"  // __throw_system_error +#include <time.h>        // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME + +#if !defined(CLOCK_REALTIME) +#include <sys/time.h>        // for gettimeofday and timeval +#endif + +#if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(CLOCK_MONOTONIC) +#if __APPLE__  #include <mach/mach_time.h>  // mach_absolute_time, mach_timebase_info_data_t -#else  /* !__APPLE__ */ -#include <cerrno>  // errno -#include <system_error>  // __throw_system_error -#include <time.h>  // clock_gettime, CLOCK_MONOTONIC -#endif  // __APPLE__ +#else +#error "Monotonic clock not implemented" +#endif +#endif  _LIBCPP_BEGIN_NAMESPACE_STD @@ -29,9 +36,16 @@ const bool system_clock::is_steady;  system_clock::time_point  system_clock::now() _NOEXCEPT  { +#ifdef CLOCK_REALTIME +    struct timespec tp; +    if (0 != clock_gettime(CLOCK_REALTIME, &tp)) +        __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed"); +    return time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000)); +#else  // !CLOCK_REALTIME      timeval tv;      gettimeofday(&tv, 0);      return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); +#endif  // CLOCK_REALTIME  }  time_t @@ -48,10 +62,26 @@ system_clock::from_time_t(time_t t) _NOEXCEPT  #ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK  // steady_clock +// +// Warning:  If this is not truly steady, then it is non-conforming.  It is +//  better for it to not exist and have the rest of libc++ use system_clock +//  instead.  const bool steady_clock::is_steady; -#ifdef __APPLE__ +#ifdef CLOCK_MONOTONIC + +steady_clock::time_point +steady_clock::now() _NOEXCEPT +{ +    struct timespec tp; +    if (0 != clock_gettime(CLOCK_MONOTONIC, &tp)) +        __throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed"); +    return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); +} + +#elif defined(__APPLE__) +  //   mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of  //   nanoseconds since the computer booted up.  MachInfo.numer and MachInfo.denom  //   are run time constants supplied by the OS.  This clock has no relationship @@ -108,23 +138,9 @@ steady_clock::now() _NOEXCEPT      return time_point(duration(fp()));  } -#else  // __APPLE__ -// FIXME: if _LIBCPP_HAS_NO_MONOTONIC_CLOCK, then clock_gettime isn't going to -// work. It may be possible to fall back on something else, depending on the system. - -// Warning:  If this is not truly steady, then it is non-conforming.  It is -//  better for it to not exist and have the rest of libc++ use system_clock -//  instead. - -steady_clock::time_point -steady_clock::now() _NOEXCEPT -{ -    struct timespec tp; -    if (0 != clock_gettime(CLOCK_MONOTONIC, &tp)) -        __throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed"); -    return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); -} -#endif  // __APPLE__ +#else +#error "Monotonic clock not implemented" +#endif  #endif // !_LIBCPP_HAS_NO_MONOTONIC_CLOCK diff --git a/contrib/libc++/src/config_elast.h b/contrib/libc++/src/config_elast.h new file mode 100644 index 000000000000..9d6a76b0c004 --- /dev/null +++ b/contrib/libc++/src/config_elast.h @@ -0,0 +1,36 @@ +//===----------------------- config_elast.h -------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CONFIG_ELAST +#define _LIBCPP_CONFIG_ELAST + +#if defined(_WIN32) +#include <stdlib.h> +#else +#include <errno.h> +#endif + +#if defined(ELAST) +#define _LIBCPP_ELAST ELAST +#elif defined(_NEWLIB_VERSION) +#define _LIBCPP_ELAST __ELASTERROR +#elif defined(__linux__) +#define _LIBCPP_ELAST 4095 +#elif defined(__APPLE__) +// No _LIBCPP_ELAST needed on Apple +#elif defined(__sun__) +#define _LIBCPP_ELAST ESTALE +#elif defined(_WIN32) +#define _LIBCPP_ELAST _sys_nerr +#else +// Warn here so that the person doing the libcxx port has an easier time: +#warning ELAST for this platform not yet implemented +#endif + +#endif // _LIBCPP_CONFIG_ELAST diff --git a/contrib/libc++/src/debug.cpp b/contrib/libc++/src/debug.cpp index 60694a3bdb0e..b1a16e6e72d4 100644 --- a/contrib/libc++/src/debug.cpp +++ b/contrib/libc++/src/debug.cpp @@ -214,10 +214,10 @@ __libcpp_db::__erase_i(void* __i)              else                  q->__next_ = p->__next_;              __c_node* c = p->__c_; -            free(p);              --__isz_;              if (c != nullptr)                  c->__remove(p); +            free(p);          }      }  } diff --git a/contrib/libc++/src/exception.cpp b/contrib/libc++/src/exception.cpp index b5c46c0805ec..2c16060a7583 100644 --- a/contrib/libc++/src/exception.cpp +++ b/contrib/libc++/src/exception.cpp @@ -29,7 +29,7 @@      #define __terminate_handler  __cxxabiapple::__cxa_terminate_handler      #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler    #endif  // _LIBCPPABI_VERSION -#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>) +#elif defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI) || __has_include(<cxxabi.h>)    #include <cxxabi.h>    using namespace __cxxabiv1;    #if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION) @@ -90,14 +90,14 @@ terminate() _NOEXCEPT  #endif  // _LIBCPP_NO_EXCEPTIONS          (*get_terminate())();          // handler should not return -        printf("terminate_handler unexpectedly returned\n"); +        fprintf(stderr, "terminate_handler unexpectedly returned\n");          ::abort();  #ifndef _LIBCPP_NO_EXCEPTIONS      }      catch (...)      {          // handler should not throw exception -        printf("terminate_handler unexpectedly threw an exception\n"); +        fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");          ::abort();      }  #endif  // _LIBCPP_NO_EXCEPTIONS @@ -106,18 +106,24 @@ terminate() _NOEXCEPT  #endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)  #if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(__EMSCRIPTEN__) -bool uncaught_exception() _NOEXCEPT +bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; } + +int uncaught_exceptions() _NOEXCEPT  {  #if defined(__APPLE__) || defined(_LIBCPPABI_VERSION) -    // on Darwin, there is a helper function so __cxa_get_globals is private -    return __cxa_uncaught_exception(); +   // on Darwin, there is a helper function so __cxa_get_globals is private +# if _LIBCPPABI_VERSION > 1101 +    return __cxa_uncaught_exceptions(); +# else +    return __cxa_uncaught_exception() ? 1 : 0; +# endif  #else  // __APPLE__  #   if defined(_MSC_VER) && ! defined(__clang__) -        _LIBCPP_WARNING("uncaught_exception not yet implemented") +        _LIBCPP_WARNING("uncaught_exceptions not yet implemented")  #   else  #       warning uncaught_exception not yet implemented  #   endif -    printf("uncaught_exception not yet implemented\n"); +    fprintf(stderr, "uncaught_exceptions not yet implemented\n");      ::abort();  #endif  // __APPLE__  } @@ -190,7 +196,7 @@ exception_ptr::~exception_ptr() _NOEXCEPT  #   else  #       warning exception_ptr not yet implemented  #   endif -    printf("exception_ptr not yet implemented\n"); +    fprintf(stderr, "exception_ptr not yet implemented\n");      ::abort();  #endif  } @@ -209,7 +215,7 @@ exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT  #   else  #       warning exception_ptr not yet implemented  #   endif -    printf("exception_ptr not yet implemented\n"); +    fprintf(stderr, "exception_ptr not yet implemented\n");      ::abort();  #endif  } @@ -234,7 +240,7 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT  #   else  #       warning exception_ptr not yet implemented  #   endif -    printf("exception_ptr not yet implemented\n"); +    fprintf(stderr, "exception_ptr not yet implemented\n");      ::abort();  #endif  } @@ -278,7 +284,7 @@ exception_ptr current_exception() _NOEXCEPT  #   else  #       warning exception_ptr not yet implemented  #   endif -    printf("exception_ptr not yet implemented\n"); +    fprintf(stderr, "exception_ptr not yet implemented\n");      ::abort();  #endif  } @@ -300,7 +306,7 @@ void rethrow_exception(exception_ptr p)  #   else  #       warning exception_ptr not yet implemented  #   endif -    printf("exception_ptr not yet implemented\n"); +    fprintf(stderr, "exception_ptr not yet implemented\n");      ::abort();  #endif  } diff --git a/contrib/libc++/src/future.cpp b/contrib/libc++/src/future.cpp index 0c5c2c4488d2..3132b1861af2 100644 --- a/contrib/libc++/src/future.cpp +++ b/contrib/libc++/src/future.cpp @@ -98,7 +98,6 @@ __assoc_sub_state::set_value()  #endif      __state_ |= __constructed | ready;      __cv_.notify_all(); -    __lk.unlock();  }  void @@ -111,7 +110,6 @@ __assoc_sub_state::set_value_at_thread_exit()  #endif      __state_ |= __constructed;      __thread_local_data()->__make_ready_at_thread_exit(this); -    __lk.unlock();  }  void @@ -124,7 +122,6 @@ __assoc_sub_state::set_exception(exception_ptr __p)  #endif      __exception_ = __p;      __state_ |= ready; -    __lk.unlock();      __cv_.notify_all();  } @@ -138,7 +135,6 @@ __assoc_sub_state::set_exception_at_thread_exit(exception_ptr __p)  #endif      __exception_ = __p;      __thread_local_data()->__make_ready_at_thread_exit(this); -    __lk.unlock();  }  void @@ -146,7 +142,6 @@ __assoc_sub_state::__make_ready()  {      unique_lock<mutex> __lk(__mut_);      __state_ |= ready; -    __lk.unlock();      __cv_.notify_all();  } diff --git a/contrib/libc++/src/ios.cpp b/contrib/libc++/src/ios.cpp index d879beb3801f..90972c407d79 100644 --- a/contrib/libc++/src/ios.cpp +++ b/contrib/libc++/src/ios.cpp @@ -8,16 +8,20 @@  //===----------------------------------------------------------------------===//  #include "__config" +  #include "ios" -#include "streambuf" -#include "istream" -#include "string" + +#include <stdlib.h> +  #include "__locale"  #include "algorithm" +#include "config_elast.h" +#include "istream" +#include "limits"  #include "memory"  #include "new" -#include "limits" -#include <stdlib.h> +#include "streambuf" +#include "string"  _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/contrib/libc++/src/iostream.cpp b/contrib/libc++/src/iostream.cpp index 7102e4389e06..e073aec6ead5 100644 --- a/contrib/libc++/src/iostream.cpp +++ b/contrib/libc++/src/iostream.cpp @@ -13,55 +13,75 @@  _LIBCPP_BEGIN_NAMESPACE_STD -static mbstate_t state_types[6] = {}; - +#ifndef _LIBCPP_HAS_NO_STDIN +_ALIGNAS_TYPE (istream)  _LIBCPP_FUNC_VIS char cin [sizeof(istream)];  _ALIGNAS_TYPE (__stdinbuf<char> ) static char __cin [sizeof(__stdinbuf <char>)]; -_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)]; -_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)]; +static mbstate_t mb_cin; +_ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin [sizeof(wistream)];  _ALIGNAS_TYPE (__stdinbuf<wchar_t> ) static char __wcin [sizeof(__stdinbuf <wchar_t>)]; -_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)]; -_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)]; +static mbstate_t mb_wcin; +#endif -_ALIGNAS_TYPE (istream)  _LIBCPP_FUNC_VIS char cin [sizeof(istream)]; +#ifndef _LIBCPP_HAS_NO_STDOUT  _ALIGNAS_TYPE (ostream)  _LIBCPP_FUNC_VIS char cout[sizeof(ostream)]; -_ALIGNAS_TYPE (ostream)  _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)]; -_ALIGNAS_TYPE (ostream)  _LIBCPP_FUNC_VIS char clog[sizeof(ostream)]; -_ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin [sizeof(wistream)]; +_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)]; +static mbstate_t mb_cout;  _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcout[sizeof(wostream)]; +_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)]; +static mbstate_t mb_wcout; +#endif + +_ALIGNAS_TYPE (ostream)  _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)]; +_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)]; +static mbstate_t mb_cerr;  _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcerr[sizeof(wostream)]; +_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)]; +static mbstate_t mb_wcerr; + +_ALIGNAS_TYPE (ostream)  _LIBCPP_FUNC_VIS char clog[sizeof(ostream)];  _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)];  ios_base::Init __start_std_streams;  ios_base::Init::Init()  { -    istream* cin_ptr  = ::new(cin)  istream(::new(__cin)  __stdinbuf <char>(stdin, state_types+0) ); -    ostream* cout_ptr = ::new(cout) ostream(::new(__cout) __stdoutbuf<char>(stdout, state_types+1)); -    ostream* cerr_ptr = ::new(cerr) ostream(::new(__cerr) __stdoutbuf<char>(stderr, state_types+2)); +#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)); +#endif +#ifndef _LIBCPP_HAS_NO_STDOUT +    ostream* cout_ptr = ::new(cout) ostream(::new(__cout) __stdoutbuf<char>(stdout, &mb_cout)); +    wostream* wcout_ptr = ::new(wcout) wostream(::new(__wcout) __stdoutbuf<wchar_t>(stdout, &mb_wcout)); +#endif +    ostream* cerr_ptr = ::new(cerr) ostream(::new(__cerr) __stdoutbuf<char>(stderr, &mb_cerr));                          ::new(clog) ostream(cerr_ptr->rdbuf()); -    cin_ptr->tie(cout_ptr); -    _VSTD::unitbuf(*cerr_ptr); -    cerr_ptr->tie(cout_ptr); - -    wistream* wcin_ptr  = ::new(wcin)  wistream(::new(__wcin)  __stdinbuf <wchar_t>(stdin, state_types+3) ); -    wostream* wcout_ptr = ::new(wcout) wostream(::new(__wcout) __stdoutbuf<wchar_t>(stdout, state_types+4)); -    wostream* wcerr_ptr = ::new(wcerr) wostream(::new(__wcerr) __stdoutbuf<wchar_t>(stderr, state_types+5)); +    wostream* wcerr_ptr = ::new(wcerr) wostream(::new(__wcerr) __stdoutbuf<wchar_t>(stderr, &mb_wcerr));                            ::new(wclog) wostream(wcerr_ptr->rdbuf()); + +#if !defined(_LIBCPP_HAS_NO_STDIN) && !defined(_LIBCPP_HAS_NO_STDOUT) +    cin_ptr->tie(cout_ptr);      wcin_ptr->tie(wcout_ptr); +#endif +    _VSTD::unitbuf(*cerr_ptr);      _VSTD::unitbuf(*wcerr_ptr); +#ifndef _LIBCPP_HAS_NO_STDOUT +    cerr_ptr->tie(cout_ptr);      wcerr_ptr->tie(wcout_ptr); +#endif  }  ios_base::Init::~Init()  { +#ifndef _LIBCPP_HAS_NO_STDOUT      ostream* cout_ptr = reinterpret_cast<ostream*>(cout); -    ostream* clog_ptr = reinterpret_cast<ostream*>(clog); +    wostream* wcout_ptr = reinterpret_cast<wostream*>(wcout);      cout_ptr->flush(); -    clog_ptr->flush(); +    wcout_ptr->flush(); +#endif -    wostream* wcout_ptr = reinterpret_cast<wostream*>(wcout); +    ostream* clog_ptr = reinterpret_cast<ostream*>(clog);      wostream* wclog_ptr = reinterpret_cast<wostream*>(wclog); -    wcout_ptr->flush(); +    clog_ptr->flush();      wclog_ptr->flush();  } diff --git a/contrib/libc++/src/locale.cpp b/contrib/libc++/src/locale.cpp index f21e35dd540a..bdc73e1d5379 100644 --- a/contrib/libc++/src/locale.cpp +++ b/contrib/libc++/src/locale.cpp @@ -27,7 +27,7 @@  #include "cwctype"  #include "__sso_allocator"  #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) -#include <support/win32/locale_win32.h> +#include "support/win32/locale_win32.h"  #elif !defined(__ANDROID__)  #include <langinfo.h>  #endif @@ -575,8 +575,10 @@ locale::global(const locale& loc)      locale& g = __global();      locale r = g;      g = loc; +#ifndef __CloudABI__      if (g.name() != "*")          setlocale(LC_ALL, g.name().c_str()); +#endif      return r;  } @@ -813,7 +815,7 @@ ctype<wchar_t>::do_toupper(char_type c) const  #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)      return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;  #else -    return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c; +    return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;  #endif  } @@ -827,7 +829,7 @@ ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const          *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]                               : *low;  #else -        *low = (isascii(*low) && islower_l(*low, __cloc())) ? (*low-L'a'+L'A') : *low; +        *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;  #endif      return low;  } @@ -840,7 +842,7 @@ ctype<wchar_t>::do_tolower(char_type c) const  #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)      return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;  #else -    return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c; +    return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;  #endif  } @@ -854,7 +856,7 @@ ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const          *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]                               : *low;  #else -        *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-L'A'+L'a' : *low; +        *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;  #endif      return low;  } @@ -923,7 +925,7 @@ ctype<char>::do_toupper(char_type c) const      return isascii(c) ?         static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;  #else -    return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c; +    return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;  #endif  } @@ -940,7 +942,7 @@ ctype<char>::do_toupper(char_type* low, const char_type* high) const          *low = isascii(*low) ?            static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;  #else -        *low = (isascii(*low) && islower_l(*low, __cloc())) ? *low-'a'+'A' : *low; +        *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;  #endif      return low;  } @@ -957,7 +959,7 @@ ctype<char>::do_tolower(char_type c) const      return isascii(c) ?        static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;  #else -    return (isascii(c) && isupper_l(c, __cloc())) ? c-'A'+'a' : c; +    return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;  #endif  } @@ -972,7 +974,7 @@ ctype<char>::do_tolower(char_type* low, const char_type* high) const  #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)          *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;  #else -        *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low; +        *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;  #endif      return low;  } @@ -1016,6 +1018,87 @@ extern "C" const int ** __ctype_tolower_loc();  extern "C" const int ** __ctype_toupper_loc();  #endif +#ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE +const ctype<char>::mask* +ctype<char>::classic_table()  _NOEXCEPT +{ +    static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = { +        cntrl,                          cntrl, +        cntrl,                          cntrl, +        cntrl,                          cntrl, +        cntrl,                          cntrl, +        cntrl,                          cntrl | space | blank, +        cntrl | space,                  cntrl | space, +        cntrl | space,                  cntrl | space, +        cntrl,                          cntrl, +        cntrl,                          cntrl, +        cntrl,                          cntrl, +        cntrl,                          cntrl, +        cntrl,                          cntrl, +        cntrl,                          cntrl, +        cntrl,                          cntrl, +        cntrl,                          cntrl, +        cntrl,                          cntrl, +        space | blank | print,          punct | print, +        punct | print,                  punct | print, +        punct | print,                  punct | print, +        punct | print,                  punct | print, +        punct | print,                  punct | print, +        punct | print,                  punct | print, +        punct | print,                  punct | print, +        punct | print,                  punct | print, +        digit | print | xdigit,         digit | print | xdigit, +        digit | print | xdigit,         digit | print | xdigit, +        digit | print | xdigit,         digit | print | xdigit, +        digit | print | xdigit,         digit | print | xdigit, +        digit | print | xdigit,         digit | print | xdigit, +        punct | print,                  punct | print, +        punct | print,                  punct | print, +        punct | print,                  punct | print, +        punct | print,                  upper | xdigit | print | alpha, +        upper | xdigit | print | alpha, upper | xdigit | print | alpha, +        upper | xdigit | print | alpha, upper | xdigit | print | alpha, +        upper | xdigit | print | alpha, upper | print | alpha, +        upper | print | alpha,          upper | print | alpha, +        upper | print | alpha,          upper | print | alpha, +        upper | print | alpha,          upper | print | alpha, +        upper | print | alpha,          upper | print | alpha, +        upper | print | alpha,          upper | print | alpha, +        upper | print | alpha,          upper | print | alpha, +        upper | print | alpha,          upper | print | alpha, +        upper | print | alpha,          upper | print | alpha, +        upper | print | alpha,          upper | print | alpha, +        upper | print | alpha,          punct | print, +        punct | print,                  punct | print, +        punct | print,                  punct | print, +        punct | print,                  lower | xdigit | print | alpha, +        lower | xdigit | print | alpha, lower | xdigit | print | alpha, +        lower | xdigit | print | alpha, lower | xdigit | print | alpha, +        lower | xdigit | print | alpha, lower | print | alpha, +        lower | print | alpha,          lower | print | alpha, +        lower | print | alpha,          lower | print | alpha, +        lower | print | alpha,          lower | print | alpha, +        lower | print | alpha,          lower | print | alpha, +        lower | print | alpha,          lower | print | alpha, +        lower | print | alpha,          lower | print | alpha, +        lower | print | alpha,          lower | print | alpha, +        lower | print | alpha,          lower | print | alpha, +        lower | print | alpha,          lower | print | alpha, +        lower | print | alpha,          punct | print, +        punct | print,                  punct | print, +        punct | print,                  cntrl, +        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +    }; +    return builtin_table; +} +#else  const ctype<char>::mask*  ctype<char>::classic_table()  _NOEXCEPT  { @@ -1024,7 +1107,7 @@ ctype<char>::classic_table()  _NOEXCEPT  #elif defined(__NetBSD__)      return _C_ctype_tab_ + 1;  #elif defined(__GLIBC__) -    return __cloc()->__ctype_b; +    return _LIBCPP_GET_C_LOCALE->__ctype_b;  #elif __sun__      return __ctype_mask;  #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) @@ -1033,10 +1116,11 @@ ctype<char>::classic_table()  _NOEXCEPT  // going to end up dereferencing it later...  #elif defined(__EMSCRIPTEN__)      return *__ctype_b_loc(); +#elif defined(_NEWLIB_VERSION) +    // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1]. +    return _ctype_ + 1;  #elif defined(_AIX)      return (const unsigned int *)__lc_ctype_ptr->obj->mask; -#elif defined(__ANDROID__) -    return reinterpret_cast<const unsigned char*>(_ctype_) + 1;  #else      // Platform not supported: abort so the person doing the port knows what to      // fix @@ -1046,18 +1130,19 @@ ctype<char>::classic_table()  _NOEXCEPT      return NULL;  #endif  } +#endif  #if defined(__GLIBC__)  const int*  ctype<char>::__classic_lower_table() _NOEXCEPT  { -    return __cloc()->__ctype_tolower; +    return _LIBCPP_GET_C_LOCALE->__ctype_tolower;  }  const int*  ctype<char>::__classic_upper_table() _NOEXCEPT  { -    return __cloc()->__ctype_toupper; +    return _LIBCPP_GET_C_LOCALE->__ctype_toupper;  }  #elif __NetBSD__  const short* @@ -1180,16 +1265,16 @@ ctype_byname<wchar_t>::do_is(mask m, char_type c) const  #else      bool result = false;      wint_t ch = static_cast<wint_t>(c); -    if (m & space) result |= (iswspace_l(ch, __l) != 0); -    if (m & print) result |= (iswprint_l(ch, __l) != 0); -    if (m & cntrl) result |= (iswcntrl_l(ch, __l) != 0); -    if (m & upper) result |= (iswupper_l(ch, __l) != 0); -    if (m & lower) result |= (iswlower_l(ch, __l) != 0); -    if (m & alpha) result |= (iswalpha_l(ch, __l) != 0); -    if (m & digit) result |= (iswdigit_l(ch, __l) != 0); -    if (m & punct) result |= (iswpunct_l(ch, __l) != 0); -    if (m & xdigit) result |= (iswxdigit_l(ch, __l) != 0); -    if (m & blank) result |= (iswblank_l(ch, __l) != 0); +    if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0); +    if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0); +    if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0); +    if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0); +    if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0); +    if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0); +    if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0); +    if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0); +    if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0); +    if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0);      return result;  #endif  } @@ -1207,22 +1292,32 @@ ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask*              wint_t ch = static_cast<wint_t>(*low);              if (iswspace_l(ch, __l))                  *vec |= space; +#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT              if (iswprint_l(ch, __l))                  *vec |= print; +#endif              if (iswcntrl_l(ch, __l))                  *vec |= cntrl;              if (iswupper_l(ch, __l))                  *vec |= upper;              if (iswlower_l(ch, __l))                  *vec |= lower; +#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA              if (iswalpha_l(ch, __l))                  *vec |= alpha; +#endif              if (iswdigit_l(ch, __l))                  *vec |= digit;              if (iswpunct_l(ch, __l))                  *vec |= punct; +#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT              if (iswxdigit_l(ch, __l))                  *vec |= xdigit; +#endif +#if !defined(__sun__) +            if (iswblank_l(ch, __l)) +                *vec |= blank; +#endif          }      }      return low; @@ -1238,16 +1333,16 @@ ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type*              break;  #else          wint_t ch = static_cast<wint_t>(*low); -        if (m & space && iswspace_l(ch, __l)) break; -        if (m & print && iswprint_l(ch, __l)) break; -        if (m & cntrl && iswcntrl_l(ch, __l)) break; -        if (m & upper && iswupper_l(ch, __l)) break; -        if (m & lower && iswlower_l(ch, __l)) break; -        if (m & alpha && iswalpha_l(ch, __l)) break; -        if (m & digit && iswdigit_l(ch, __l)) break; -        if (m & punct && iswpunct_l(ch, __l)) break; -        if (m & xdigit && iswxdigit_l(ch, __l)) break; -        if (m & blank && iswblank_l(ch, __l)) break; +        if ((m & space) == space && iswspace_l(ch, __l)) break; +        if ((m & print) == print && iswprint_l(ch, __l)) break; +        if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break; +        if ((m & upper) == upper && iswupper_l(ch, __l)) break; +        if ((m & lower) == lower && iswlower_l(ch, __l)) break; +        if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break; +        if ((m & digit) == digit && iswdigit_l(ch, __l)) break; +        if ((m & punct) == punct && iswpunct_l(ch, __l)) break; +        if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break; +        if ((m & blank) == blank && iswblank_l(ch, __l)) break;  #endif      }      return low; @@ -1263,16 +1358,16 @@ ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type              break;  #else          wint_t ch = static_cast<wint_t>(*low); -        if (m & space && iswspace_l(ch, __l)) continue; -        if (m & print && iswprint_l(ch, __l)) continue; -        if (m & cntrl && iswcntrl_l(ch, __l)) continue; -        if (m & upper && iswupper_l(ch, __l)) continue; -        if (m & lower && iswlower_l(ch, __l)) continue; -        if (m & alpha && iswalpha_l(ch, __l)) continue; -        if (m & digit && iswdigit_l(ch, __l)) continue; -        if (m & punct && iswpunct_l(ch, __l)) continue; -        if (m & xdigit && iswxdigit_l(ch, __l)) continue; -        if (m & blank && iswblank_l(ch, __l)) continue; +        if ((m & space) == space && iswspace_l(ch, __l)) continue; +        if ((m & print) == print && iswprint_l(ch, __l)) continue; +        if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue; +        if ((m & upper) == upper && iswupper_l(ch, __l)) continue; +        if ((m & lower) == lower && iswlower_l(ch, __l)) continue; +        if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue; +        if ((m & digit) == digit && iswdigit_l(ch, __l)) continue; +        if ((m & punct) == punct && iswpunct_l(ch, __l)) continue; +        if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue; +        if ((m & blank) == blank && iswblank_l(ch, __l)) continue;          break;  #endif      } @@ -1564,7 +1659,7 @@ codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,              frm_nxt = frm;              return frm_nxt == frm_end ? ok : partial;          } -        if (n == 0) +        if (n == size_t(-1))              return error;          to_nxt += n;          if (to_nxt == to_end) @@ -1614,22 +1709,23 @@ codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,  int  codecvt<wchar_t, char, mbstate_t>::do_encoding() const  _NOEXCEPT  { +#ifndef __CloudABI__  #ifdef _LIBCPP_LOCALE__L_EXTENSIONS -    if (mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) == 0) +    if (mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)  #else -    if (__mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) == 0) +    if (__mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)  #endif -    { -        // stateless encoding +        return -1; +#endif + +    // stateless encoding  #ifdef _LIBCPP_LOCALE__L_EXTENSIONS -        if (__l == 0 || MB_CUR_MAX_L(__l) == 1)  // there are no known constant length encodings +    if (__l == 0 || MB_CUR_MAX_L(__l) == 1)  // there are no known constant length encodings  #else -        if (__l == 0 || __mb_cur_max_l(__l) == 1)  // there are no known constant length encodings +    if (__l == 0 || __mb_cur_max_l(__l) == 1)  // there are no known constant length encodings  #endif -            return 1;                // which take more than 1 char to form a wchar_t -         return 0; -    } -    return -1; +        return 1;                // which take more than 1 char to form a wchar_t +    return 0;  }  bool diff --git a/contrib/libc++/src/memory.cpp b/contrib/libc++/src/memory.cpp index 8a4eb34811f2..66fb143c6a62 100644 --- a/contrib/libc++/src/memory.cpp +++ b/contrib/libc++/src/memory.cpp @@ -13,24 +13,28 @@  #include "mutex"  #include "thread"  #endif +#include "support/atomic_support.h"  _LIBCPP_BEGIN_NAMESPACE_STD  namespace  { +// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively) +// should be sufficient for thread safety. +// See https://llvm.org/bugs/show_bug.cgi?id=22803  template <class T>  inline T  increment(T& t) _NOEXCEPT  { -    return __sync_add_and_fetch(&t, 1); +    return __libcpp_atomic_add(&t, 1, _AO_Relaxed);  }  template <class T>  inline T  decrement(T& t) _NOEXCEPT  { -    return __sync_add_and_fetch(&t, -1); +    return __libcpp_atomic_add(&t, -1, _AO_Acq_Rel);  }  }  // namespace @@ -99,14 +103,13 @@ __shared_weak_count::__release_weak() _NOEXCEPT  __shared_weak_count*  __shared_weak_count::lock() _NOEXCEPT  { -    long object_owners = __shared_owners_; +    long object_owners = __libcpp_atomic_load(&__shared_owners_);      while (object_owners != -1)      { -        if (__sync_bool_compare_and_swap(&__shared_owners_, -                                         object_owners, -                                         object_owners+1)) +        if (__libcpp_atomic_compare_exchange(&__shared_owners_, +                                             &object_owners, +                                             object_owners+1))              return this; -        object_owners = __shared_owners_;      }      return 0;  } diff --git a/contrib/libc++/src/mutex.cpp b/contrib/libc++/src/mutex.cpp index e56271d308e6..5f8ba0a08266 100644 --- a/contrib/libc++/src/mutex.cpp +++ b/contrib/libc++/src/mutex.cpp @@ -12,6 +12,7 @@  #include "limits"  #include "system_error"  #include "cassert" +#include "support/atomic_support.h"  _LIBCPP_BEGIN_NAMESPACE_STD  #ifndef _LIBCPP_HAS_NO_THREADS @@ -220,6 +221,9 @@ static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;  static pthread_cond_t  cv  = PTHREAD_COND_INITIALIZER;  #endif +/// NOTE: Changes to flag are done via relaxed atomic stores +///       even though the accesses are protected by a mutex because threads +///       just entering 'call_once` concurrently read from flag.  void  __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))  { @@ -252,11 +256,11 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))          try          {  #endif  // _LIBCPP_NO_EXCEPTIONS -            flag = 1; +            __libcpp_relaxed_store(&flag, 1ul);              pthread_mutex_unlock(&mut);              func(arg);              pthread_mutex_lock(&mut); -            flag = ~0ul; +            __libcpp_relaxed_store(&flag, ~0ul);              pthread_mutex_unlock(&mut);              pthread_cond_broadcast(&cv);  #ifndef _LIBCPP_NO_EXCEPTIONS @@ -264,7 +268,7 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))          catch (...)          {              pthread_mutex_lock(&mut); -            flag = 0ul; +            __libcpp_relaxed_store(&flag, 0ul);              pthread_mutex_unlock(&mut);              pthread_cond_broadcast(&cv);              throw; diff --git a/contrib/libc++/src/new.cpp b/contrib/libc++/src/new.cpp index a88d4cc7c249..c28fcb5917cf 100644 --- a/contrib/libc++/src/new.cpp +++ b/contrib/libc++/src/new.cpp @@ -133,9 +133,16 @@ operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT  _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS  void +operator delete(void* ptr, size_t) _NOEXCEPT +{ +    ::operator delete(ptr); +} + +_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +void  operator delete[] (void* ptr) _NOEXCEPT  { -    ::operator delete (ptr); +    ::operator delete(ptr);  }  _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS @@ -145,6 +152,13 @@ operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT      ::operator delete[](ptr);  } +_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +void +operator delete[] (void* ptr, size_t) _NOEXCEPT +{ +    ::operator delete[](ptr); +} +  #endif // !__GLIBCXX__  namespace std diff --git a/contrib/libc++/src/random.cpp b/contrib/libc++/src/random.cpp index 15ed65b58cf3..4ab424eaa6e5 100644 --- a/contrib/libc++/src/random.cpp +++ b/contrib/libc++/src/random.cpp @@ -7,11 +7,10 @@  //  //===----------------------------------------------------------------------===// -#if defined(_WIN32) +#if defined(_LIBCPP_USING_WIN32_RANDOM)  // Must be defined before including stdlib.h to enable rand_s().  #define _CRT_RAND_S -#include <stdio.h> -#endif // defined(_WIN32) +#endif // defined(_LIBCPP_USING_WIN32_RANDOM)  #include "random"  #include "system_error" @@ -19,21 +18,27 @@  #if defined(__sun__)  #define rename solaris_headers_are_broken  #endif // defined(__sun__) -#if !defined(_WIN32) + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +#if defined(_LIBCPP_USING_DEV_RANDOM)  #include <fcntl.h>  #include <unistd.h> -#endif // !defined(_WIN32) -#include <errno.h> -#if defined(_LIBCPP_USING_NACL_RANDOM) +#elif defined(_LIBCPP_USING_NACL_RANDOM)  #include <nacl/nacl_random.h> -#endif // defined(_LIBCPP_USING_NACL_RANDOM) +#endif +  _LIBCPP_BEGIN_NAMESPACE_STD -#if defined(_WIN32) +#if defined(_LIBCPP_USING_ARC4_RANDOM) -random_device::random_device(const string&) +random_device::random_device(const string& __token)  { +    if (__token != "/dev/urandom") +        __throw_system_error(ENOENT, ("random device not supported " + __token).c_str());  }  random_device::~random_device() @@ -43,10 +48,43 @@ random_device::~random_device()  unsigned  random_device::operator()()  { +    return arc4random(); +} + +#elif defined(_LIBCPP_USING_DEV_RANDOM) + +random_device::random_device(const string& __token) +    : __f_(open(__token.c_str(), O_RDONLY)) +{ +    if (__f_ < 0) +        __throw_system_error(errno, ("random_device failed to open " + __token).c_str()); +} + +random_device::~random_device() +{ +    close(__f_); +} + +unsigned +random_device::operator()() +{      unsigned r; -    errno_t err = rand_s(&r); -    if (err) -        __throw_system_error(err, "random_device rand_s failed."); +    size_t n = sizeof(r); +    char* p = reinterpret_cast<char*>(&r); +    while (n > 0) +    { +        ssize_t s = read(__f_, p, n); +        if (s == 0) +            __throw_system_error(ENODATA, "random_device got EOF"); +        if (s == -1) +        { +            if (errno != EINTR) +                __throw_system_error(errno, "random_device got an unexpected error"); +            continue; +        } +        n -= static_cast<size_t>(s); +        p += static_cast<size_t>(s); +    }      return r;  } @@ -70,7 +108,6 @@ random_device::operator()()  {      unsigned r;      size_t n = sizeof(r); -    char* p = reinterpret_cast<char*>(&r);      size_t bytes_written;      int error = nacl_secure_random(&r, n, &bytes_written);      if (error != 0) @@ -80,44 +117,31 @@ random_device::operator()()      return r;  } -#else // !defined(_WIN32) && !defined(_LIBCPP_USING_NACL_RANDOM) +#elif defined(_LIBCPP_USING_WIN32_RANDOM)  random_device::random_device(const string& __token) -    : __f_(open(__token.c_str(), O_RDONLY))  { -    if (__f_ < 0) -        __throw_system_error(errno, ("random_device failed to open " + __token).c_str()); +    if (__token != "/dev/urandom") +        __throw_system_error(ENOENT, ("random device not supported " + __token).c_str());  }  random_device::~random_device()  { -    close(__f_);  }  unsigned  random_device::operator()()  {      unsigned r; -    size_t n = sizeof(r); -    char* p = reinterpret_cast<char*>(&r); -    while (n > 0) -    { -        ssize_t s = read(__f_, p, n); -        if (s == 0) -            __throw_system_error(ENODATA, "random_device got EOF"); -        if (s == -1) -        { -            if (errno != EINTR) -                __throw_system_error(errno, "random_device got an unexpected error"); -            continue; -        } -        n -= static_cast<size_t>(s); -        p += static_cast<size_t>(s); -    } +    errno_t err = rand_s(&r); +    if (err) +        __throw_system_error(err, "random_device rand_s failed.");      return r;  } -#endif // defined(_WIN32) || defined(_LIBCPP_USING_NACL_RANDOM) +#else +#error "Random device not implemented for this architecture" +#endif  double  random_device::entropy() const _NOEXCEPT diff --git a/contrib/libc++/src/shared_mutex.cpp b/contrib/libc++/src/shared_mutex.cpp index 2b78c1feb9f5..874aceb1b03a 100644 --- a/contrib/libc++/src/shared_mutex.cpp +++ b/contrib/libc++/src/shared_mutex.cpp @@ -15,7 +15,8 @@  _LIBCPP_BEGIN_NAMESPACE_STD -shared_timed_mutex::shared_timed_mutex() +// Shared Mutex Base +__shared_mutex_base::__shared_mutex_base()      : __state_(0)  {  } @@ -23,7 +24,7 @@ shared_timed_mutex::shared_timed_mutex()  // Exclusive ownership  void -shared_timed_mutex::lock() +__shared_mutex_base::lock()  {      unique_lock<mutex> lk(__mut_);      while (__state_ & __write_entered_) @@ -34,7 +35,7 @@ shared_timed_mutex::lock()  }  bool -shared_timed_mutex::try_lock() +__shared_mutex_base::try_lock()  {      unique_lock<mutex> lk(__mut_);      if (__state_ == 0) @@ -46,7 +47,7 @@ shared_timed_mutex::try_lock()  }  void -shared_timed_mutex::unlock() +__shared_mutex_base::unlock()  {      lock_guard<mutex> _(__mut_);      __state_ = 0; @@ -56,7 +57,7 @@ shared_timed_mutex::unlock()  // Shared ownership  void -shared_timed_mutex::lock_shared() +__shared_mutex_base::lock_shared()  {      unique_lock<mutex> lk(__mut_);      while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_) @@ -67,7 +68,7 @@ shared_timed_mutex::lock_shared()  }  bool -shared_timed_mutex::try_lock_shared() +__shared_mutex_base::try_lock_shared()  {      unique_lock<mutex> lk(__mut_);      unsigned num_readers = __state_ & __n_readers_; @@ -82,7 +83,7 @@ shared_timed_mutex::try_lock_shared()  }  void -shared_timed_mutex::unlock_shared() +__shared_mutex_base::unlock_shared()  {      lock_guard<mutex> _(__mut_);      unsigned num_readers = (__state_ & __n_readers_) - 1; @@ -101,6 +102,16 @@ shared_timed_mutex::unlock_shared()  } +// Shared Timed Mutex +// These routines are here for ABI stability +shared_timed_mutex::shared_timed_mutex() : __base() {} +void shared_timed_mutex::lock()     { return __base.lock(); } +bool shared_timed_mutex::try_lock() { return __base.try_lock(); } +void shared_timed_mutex::unlock()   { return __base.unlock(); } +void shared_timed_mutex::lock_shared() { return __base.lock_shared(); } +bool shared_timed_mutex::try_lock_shared() { return __base.try_lock_shared(); } +void shared_timed_mutex::unlock_shared() { return __base.unlock_shared(); } +  _LIBCPP_END_NAMESPACE_STD  #endif // !_LIBCPP_HAS_NO_THREADS diff --git a/contrib/libc++/src/string.cpp b/contrib/libc++/src/string.cpp index febc53209972..d3f29df639f4 100644 --- a/contrib/libc++/src/string.cpp +++ b/contrib/libc++/src/string.cpp @@ -39,7 +39,7 @@ void throw_helper( const string& msg )  #ifndef _LIBCPP_NO_EXCEPTIONS      throw T( msg );  #else -    printf("%s\n", msg.c_str()); +    fprintf(stderr, "%s\n", msg.c_str());      abort();  #endif  } diff --git a/contrib/libc++/src/support/atomic_support.h b/contrib/libc++/src/support/atomic_support.h new file mode 100644 index 000000000000..e738a5154cd3 --- /dev/null +++ b/contrib/libc++/src/support/atomic_support.h @@ -0,0 +1,142 @@ +#ifndef ATOMIC_SUPPORT_H +#define ATOMIC_SUPPORT_H + +#include "__config" +#include "memory" // for __libcpp_relaxed_load + +#if defined(__clang__) && __has_builtin(__atomic_load_n)             \ +                       && __has_builtin(__atomic_store_n)            \ +                       && __has_builtin(__atomic_add_fetch)          \ +                       && __has_builtin(__atomic_compare_exchange_n) \ +                       && defined(__ATOMIC_RELAXED)                  \ +                       && defined(__ATOMIC_CONSUME)                  \ +                       && defined(__ATOMIC_ACQUIRE)                  \ +                       && defined(__ATOMIC_RELEASE)                  \ +                       && defined(__ATOMIC_ACQ_REL)                  \ +                       && defined(__ATOMIC_SEQ_CST) +#   define _LIBCPP_HAS_ATOMIC_BUILTINS +#elif !defined(__clang__) && defined(_GNUC_VER) && _GNUC_VER >= 407 +#   define _LIBCPP_HAS_ATOMIC_BUILTINS +#endif + +#if !defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS) +# if defined(_MSC_VER) && !defined(__clang__) +    _LIBCPP_WARNING("Building libc++ without __atomic builtins is unsupported") +# else +#   warning Building libc++ without __atomic builtins is unsupported +# endif +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace { + +#if defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS) + +enum __libcpp_atomic_order { +    _AO_Relaxed = __ATOMIC_RELAXED, +    _AO_Consume = __ATOMIC_CONSUME, +    _AO_Aquire  = __ATOMIC_ACQUIRE, +    _AO_Release = __ATOMIC_RELEASE, +    _AO_Acq_Rel = __ATOMIC_ACQ_REL, +    _AO_Seq     = __ATOMIC_SEQ_CST +}; + +template <class _ValueType, class _FromType> +inline _LIBCPP_INLINE_VISIBILITY +void __libcpp_atomic_store(_ValueType* __dest, _FromType __val, +                           int __order = _AO_Seq) +{ +    __atomic_store_n(__dest, __val, __order); +} + +template <class _ValueType, class _FromType> +inline _LIBCPP_INLINE_VISIBILITY +void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val) +{ +    __atomic_store_n(__dest, __val, _AO_Relaxed); +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_load(_ValueType const* __val, +                                int __order = _AO_Seq) +{ +    return __atomic_load_n(__val, __order); +} + +template <class _ValueType, class _AddType> +inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a, +                               int __order = _AO_Seq) +{ +    return __atomic_add_fetch(__val, __a, __order); +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY +bool __libcpp_atomic_compare_exchange(_ValueType* __val, +    _ValueType* __expected, _ValueType __after, +    int __success_order = _AO_Seq, +    int __fail_order = _AO_Seq) +{ +    return __atomic_compare_exchange_n(__val, __expected, __after, true, +                                       __success_order, __fail_order); +} + +#else // _LIBCPP_HAS_NO_THREADS + +enum __libcpp_atomic_order { +    _AO_Relaxed, +    _AO_Consume, +    _AO_Acquire, +    _AO_Release, +    _AO_Acq_Rel, +    _AO_Seq +}; + +template <class _ValueType, class _FromType> +inline _LIBCPP_INLINE_VISIBILITY +void __libcpp_atomic_store(_ValueType* __dest, _FromType __val, +                           int = 0) +{ +    *__dest = __val; +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_load(_ValueType const* __val, +                                int = 0) +{ +    return *__val; +} + +template <class _ValueType, class _AddType> +inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a, +                               int = 0) +{ +    return *__val += __a; +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY +bool __libcpp_atomic_compare_exchange(_ValueType* __val, +    _ValueType* __expected, _ValueType __after, +    int = 0, int = 0) +{ +    if (*__val == *__expected) { +        *__val = __after; +        return true; +    } +    *__expected = *__val; +    return false; +} + +#endif // _LIBCPP_HAS_NO_THREADS + +} // end namespace + +_LIBCPP_END_NAMESPACE_STD + +#endif // ATOMIC_SUPPORT_H diff --git a/contrib/libc++/src/system_error.cpp b/contrib/libc++/src/system_error.cpp index 9c8adc4f323e..18f668f071cd 100644 --- a/contrib/libc++/src/system_error.cpp +++ b/contrib/libc++/src/system_error.cpp @@ -7,11 +7,14 @@  //  //===----------------------------------------------------------------------===// -#define _LIBCPP_BUILDING_SYSTEM_ERROR  #include "__config" + +#define _LIBCPP_BUILDING_SYSTEM_ERROR  #include "system_error" -#include "string" + +#include "config_elast.h"  #include "cstring" +#include "string"  _LIBCPP_BEGIN_NAMESPACE_STD @@ -149,7 +152,7 @@ system_error::__init(const error_code& ec, string what_arg)              what_arg += ": ";          what_arg += ec.message();      } -    return _VSTD::move(what_arg); +    return what_arg;  }  system_error::system_error(error_code ec, const string& what_arg) diff --git a/contrib/libc++/src/thread.cpp b/contrib/libc++/src/thread.cpp index 6aad558abaad..bd27f2878383 100644 --- a/contrib/libc++/src/thread.cpp +++ b/contrib/libc++/src/thread.cpp @@ -17,9 +17,9 @@  #include "limits"  #include <sys/types.h>  #if !defined(_WIN32) -# if !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) +# if !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) && !defined(__CloudABI__)  #   include <sys/sysctl.h> -# endif // !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) +# endif // !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) && !defined(__CloudABI__)  # include <unistd.h>  #endif // !_WIN32  | 
