diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/exception.cpp | 1 | ||||
-rw-r--r-- | src/experimental/filesystem/directory_iterator.cpp | 37 | ||||
-rw-r--r-- | src/experimental/filesystem/operations.cpp | 22 | ||||
-rw-r--r-- | src/include/atomic_support.h | 19 | ||||
-rw-r--r-- | src/include/config_elast.h | 2 | ||||
-rw-r--r-- | src/include/refstring.h | 9 | ||||
-rw-r--r-- | src/iostream.cpp | 20 | ||||
-rw-r--r-- | src/locale.cpp | 3 | ||||
-rw-r--r-- | src/new.cpp | 10 | ||||
-rw-r--r-- | src/random.cpp | 29 | ||||
-rw-r--r-- | src/strstream.cpp | 6 | ||||
-rw-r--r-- | src/support/runtime/exception_fallback.ipp | 9 | ||||
-rw-r--r-- | src/support/runtime/exception_msvc.ipp | 107 | ||||
-rw-r--r-- | src/support/runtime/exception_pointer_msvc.ipp | 32 | ||||
-rw-r--r-- | src/support/runtime/new_handler_fallback.ipp | 4 | ||||
-rw-r--r-- | src/support/win32/locale_win32.cpp | 16 | ||||
-rw-r--r-- | src/system_error.cpp | 72 | ||||
-rw-r--r-- | src/typeinfo.cpp | 45 |
18 files changed, 333 insertions, 110 deletions
diff --git a/src/exception.cpp b/src/exception.cpp index 4359d126173a..3d2dcfd5b10e 100644 --- a/src/exception.cpp +++ b/src/exception.cpp @@ -31,6 +31,7 @@ #include "support/runtime/exception_glibcxx.ipp" #include "support/runtime/exception_pointer_glibcxx.ipp" #else +#include "include/atomic_support.h" #include "support/runtime/exception_fallback.ipp" #include "support/runtime/exception_pointer_unimplemented.ipp" #endif diff --git a/src/experimental/filesystem/directory_iterator.cpp b/src/experimental/filesystem/directory_iterator.cpp index 25135857d40c..a552fdc4461d 100644 --- a/src/experimental/filesystem/directory_iterator.cpp +++ b/src/experimental/filesystem/directory_iterator.cpp @@ -296,24 +296,43 @@ void recursive_directory_iterator::__advance(error_code* ec) { } bool recursive_directory_iterator::__try_recursion(error_code *ec) { - bool rec_sym = bool(options() & directory_options::follow_directory_symlink); + auto& curr_it = __imp_->__stack_.top(); - if (is_directory(curr_it.__entry_.status()) && - (!is_symlink(curr_it.__entry_.symlink_status()) || rec_sym)) - { - std::error_code m_ec; + bool skip_rec = false; + std::error_code m_ec; + if (!rec_sym) { + file_status st = curr_it.__entry_.symlink_status(m_ec); + if (m_ec && status_known(st)) + m_ec.clear(); + if (m_ec || is_symlink(st) || !is_directory(st)) + skip_rec = true; + } else { + file_status st = curr_it.__entry_.status(m_ec); + if (m_ec && status_known(st)) + m_ec.clear(); + if (m_ec || !is_directory(st)) + skip_rec = true; + } + + if (!skip_rec) { __dir_stream new_it(curr_it.__entry_.path(), __imp_->__options_, m_ec); if (new_it.good()) { __imp_->__stack_.push(_VSTD::move(new_it)); return true; } - if (m_ec) { - __imp_.reset(); - set_or_throw(m_ec, ec, - "recursive_directory_iterator::operator++()"); + } + if (m_ec) { + const bool allow_eacess = bool(__imp_->__options_ + & directory_options::skip_permission_denied); + if (m_ec.value() == EACCES && allow_eacess) { + if (ec) ec->clear(); + } else { + __imp_.reset(); + set_or_throw(m_ec, ec, + "recursive_directory_iterator::operator++()"); } } return false; diff --git a/src/experimental/filesystem/operations.cpp b/src/experimental/filesystem/operations.cpp index 641a3c53636d..1a514545cec5 100644 --- a/src/experimental/filesystem/operations.cpp +++ b/src/experimental/filesystem/operations.cpp @@ -182,20 +182,20 @@ void __copy(const path& from, const path& to, copy_options options, const bool sym_status2 = bool(options & copy_options::copy_symlinks); - std::error_code m_ec; + std::error_code m_ec1; struct ::stat f_st = {}; const file_status f = sym_status || sym_status2 - ? detail::posix_lstat(from, f_st, &m_ec) - : detail::posix_stat(from, f_st, &m_ec); - if (m_ec) - return set_or_throw(m_ec, ec, "copy", from, to); + ? detail::posix_lstat(from, f_st, &m_ec1) + : detail::posix_stat(from, f_st, &m_ec1); + if (m_ec1) + return set_or_throw(m_ec1, ec, "copy", from, to); struct ::stat t_st = {}; - const file_status t = sym_status ? detail::posix_lstat(to, t_st, &m_ec) - : detail::posix_stat(to, t_st, &m_ec); + const file_status t = sym_status ? detail::posix_lstat(to, t_st, &m_ec1) + : detail::posix_stat(to, t_st, &m_ec1); if (not status_known(t)) - return set_or_throw(m_ec, ec, "copy", from, to); + return set_or_throw(m_ec1, ec, "copy", from, to); if (!exists(f) || is_other(f) || is_other(t) || (is_directory(f) && is_regular_file(t)) @@ -249,9 +249,9 @@ void __copy(const path& from, const path& to, copy_options options, directory_iterator it = ec ? directory_iterator(from, *ec) : directory_iterator(from); if (ec && *ec) { return; } - std::error_code m_ec; - for (; it != directory_iterator(); it.increment(m_ec)) { - if (m_ec) return set_or_throw(m_ec, ec, "copy", from, to); + std::error_code m_ec2; + for (; it != directory_iterator(); it.increment(m_ec2)) { + if (m_ec2) return set_or_throw(m_ec2, ec, "copy", from, to); __copy(it->path(), to / it->path().filename(), options | copy_options::__in_recursive_copy, ec); if (ec && *ec) { return; } diff --git a/src/include/atomic_support.h b/src/include/atomic_support.h index 08847e630705..ccd8d78d3d71 100644 --- a/src/include/atomic_support.h +++ b/src/include/atomic_support.h @@ -16,6 +16,7 @@ #if defined(__clang__) && __has_builtin(__atomic_load_n) \ && __has_builtin(__atomic_store_n) \ && __has_builtin(__atomic_add_fetch) \ + && __has_builtin(__atomic_exchange_n) \ && __has_builtin(__atomic_compare_exchange_n) \ && defined(__ATOMIC_RELAXED) \ && defined(__ATOMIC_CONSUME) \ @@ -84,6 +85,14 @@ _ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a, template <class _ValueType> inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_exchange(_ValueType* __target, + _ValueType __value, int __order = _AO_Seq) +{ + return __atomic_exchange_n(__target, __value, __order); +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY bool __libcpp_atomic_compare_exchange(_ValueType* __val, _ValueType* __expected, _ValueType __after, int __success_order = _AO_Seq, @@ -137,6 +146,16 @@ _ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a, template <class _ValueType> inline _LIBCPP_INLINE_VISIBILITY +_ValueType __libcpp_atomic_exchange(_ValueType* __target, + _ValueType __value, int __order = _AO_Seq) +{ + _ValueType old = *__target; + *__target = __value; + return old; +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY bool __libcpp_atomic_compare_exchange(_ValueType* __val, _ValueType* __expected, _ValueType __after, int = 0, int = 0) diff --git a/src/include/config_elast.h b/src/include/config_elast.h index 8328978ef953..4c4d853c2a68 100644 --- a/src/include/config_elast.h +++ b/src/include/config_elast.h @@ -24,7 +24,7 @@ #define _LIBCPP_ELAST __ELASTERROR #elif defined(__Fuchsia__) // No _LIBCPP_ELAST needed on Fuchsia -#elif defined(__linux__) +#elif defined(__linux__) || defined(_LIBCPP_HAS_MUSL_LIBC) #define _LIBCPP_ELAST 4095 #elif defined(__APPLE__) // No _LIBCPP_ELAST needed on Apple diff --git a/src/include/refstring.h b/src/include/refstring.h index f0d5b4456da5..702f2b7388da 100644 --- a/src/include/refstring.h +++ b/src/include/refstring.h @@ -18,6 +18,7 @@ #include <dlfcn.h> #include <mach-o/dyld.h> #endif +#include "atomic_support.h" _LIBCPP_BEGIN_NAMESPACE_STD @@ -83,7 +84,7 @@ __libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) _NOEXCEPT : __imp_(s.__imp_) { if (__uses_refcount()) - __sync_add_and_fetch(&rep_from_data(__imp_)->count, 1); + __libcpp_atomic_add(&rep_from_data(__imp_)->count, 1); } inline @@ -92,10 +93,10 @@ __libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _ struct _Rep_base *old_rep = rep_from_data(__imp_); __imp_ = s.__imp_; if (__uses_refcount()) - __sync_add_and_fetch(&rep_from_data(__imp_)->count, 1); + __libcpp_atomic_add(&rep_from_data(__imp_)->count, 1); if (adjust_old_count) { - if (__sync_add_and_fetch(&old_rep->count, count_t(-1)) < 0) + if (__libcpp_atomic_add(&old_rep->count, count_t(-1)) < 0) { ::operator delete(old_rep); } @@ -107,7 +108,7 @@ inline __libcpp_refstring::~__libcpp_refstring() { if (__uses_refcount()) { _Rep_base* rep = rep_from_data(__imp_); - if (__sync_add_and_fetch(&rep->count, count_t(-1)) < 0) { + if (__libcpp_atomic_add(&rep->count, count_t(-1)) < 0) { ::operator delete(rep); } } diff --git a/src/iostream.cpp b/src/iostream.cpp index 534b47a917d5..2b47cf25b640 100644 --- a/src/iostream.cpp +++ b/src/iostream.cpp @@ -11,19 +11,23 @@ #include "string" #include "new" +#define _str(s) #s +#define str(s) _str(s) +#define _LIBCPP_NAMESPACE_STR str(_LIBCPP_NAMESPACE) + _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_HAS_NO_STDIN _ALIGNAS_TYPE (istream) _LIBCPP_FUNC_VIS char cin[sizeof(istream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?cin@__1@std@@3V?$basic_istream@DU?$char_traits@D@__1@std@@@12@A") +__asm__("?cin@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") #endif ; _ALIGNAS_TYPE (__stdinbuf<char> ) static char __cin[sizeof(__stdinbuf <char>)]; static mbstate_t mb_cin; _ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin[sizeof(wistream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?wcin@__1@std@@3V?$basic_istream@_WU?$char_traits@_W@__1@std@@@12@A") +__asm__("?wcin@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") #endif ; _ALIGNAS_TYPE (__stdinbuf<wchar_t> ) static char __wcin[sizeof(__stdinbuf <wchar_t>)]; @@ -33,14 +37,14 @@ static mbstate_t mb_wcin; #ifndef _LIBCPP_HAS_NO_STDOUT _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cout[sizeof(ostream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?cout@__1@std@@3V?$basic_ostream@DU?$char_traits@D@__1@std@@@12@A") +__asm__("?cout@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") #endif ; _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)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?wcout@__1@std@@3V?$basic_ostream@_WU?$char_traits@_W@__1@std@@@12@A") +__asm__("?wcout@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") #endif ; _ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)]; @@ -49,14 +53,14 @@ static mbstate_t mb_wcout; _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?cerr@__1@std@@3V?$basic_ostream@DU?$char_traits@D@__1@std@@@12@A") +__asm__("?cerr@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") #endif ; _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)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?wcerr@__1@std@@3V?$basic_ostream@_WU?$char_traits@_W@__1@std@@@12@A") +__asm__("?wcerr@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") #endif ; _ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)]; @@ -64,12 +68,12 @@ static mbstate_t mb_wcerr; _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char clog[sizeof(ostream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?clog@__1@std@@3V?$basic_ostream@DU?$char_traits@D@__1@std@@@12@A") +__asm__("?clog@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") #endif ; _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?wclog@__1@std@@3V?$basic_ostream@_WU?$char_traits@_W@__1@std@@@12@A") +__asm__("?wclog@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") #endif ; diff --git a/src/locale.cpp b/src/locale.cpp index 3b4c83a09007..a6cb0e97d128 100644 --- a/src/locale.cpp +++ b/src/locale.cpp @@ -36,6 +36,7 @@ #endif #include <stdlib.h> #include <stdio.h> +#include "include/atomic_support.h" #include "__undef_macros" // On Linux, wint_t and wchar_t have different signed-ness, and this causes @@ -667,7 +668,7 @@ locale::id::__get() void locale::id::__init() { - __id_ = __sync_add_and_fetch(&__next_id, 1); + __id_ = __libcpp_atomic_add(&__next_id, 1); } // template <> class collate_byname<char> diff --git a/src/new.cpp b/src/new.cpp index 2b2682fa6617..e228a0d83d8e 100644 --- a/src/new.cpp +++ b/src/new.cpp @@ -12,9 +12,12 @@ #include <stdlib.h> #include "new" +#include "include/atomic_support.h" #if defined(_LIBCPP_ABI_MICROSOFT) -// nothing todo +#if defined(_LIBCPP_NO_VCRUNTIME) +#include "support/runtime/new_handler_fallback.ipp" +#endif #elif defined(LIBCXX_BUILDING_LIBCXXABI) #include <cxxabi.h> #elif defined(LIBCXXRT) @@ -53,7 +56,8 @@ __throw_bad_alloc() } // std -#if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_MICROSOFT) && \ +#if !defined(__GLIBCXX__) && \ + (!defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME)) && \ !defined(_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS) // Implement all new and delete operators as weak definitions @@ -299,4 +303,4 @@ operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT } #endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION -#endif // !__GLIBCXX__ && !_LIBCPP_ABI_MICROSOFT && !_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS +#endif // !__GLIBCXX__ && (!_LIBCPP_ABI_MICROSOFT || _LIBCPP_NO_VCRUNTIME) && !_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS diff --git a/src/random.cpp b/src/random.cpp index eb2510a48c85..4a2468368d06 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -25,7 +25,9 @@ #include <stdio.h> #include <stdlib.h> -#if defined(_LIBCPP_USING_DEV_RANDOM) +#if defined(_LIBCPP_USING_GETENTROPY) +#include <sys/random.h> +#elif defined(_LIBCPP_USING_DEV_RANDOM) #include <fcntl.h> #include <unistd.h> #elif defined(_LIBCPP_USING_NACL_RANDOM) @@ -35,7 +37,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if defined(_LIBCPP_USING_ARC4_RANDOM) +#if defined(_LIBCPP_USING_GETENTROPY) + +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() +{ +} + +unsigned +random_device::operator()() +{ + unsigned r; + size_t n = sizeof(r); + int err = getentropy(&r, n); + if (err) + __throw_system_error(errno, "random_device getentropy failed"); + return r; +} + +#elif defined(_LIBCPP_USING_ARC4_RANDOM) random_device::random_device(const string& __token) { diff --git a/src/strstream.cpp b/src/strstream.cpp index 01523cf45462..8b8521f76af1 100644 --- a/src/strstream.cpp +++ b/src/strstream.cpp @@ -186,7 +186,7 @@ strstreambuf::overflow(int_type __c) } setg(buf, buf + ninp, buf + einp); setp(buf + einp, buf + new_size); - pbump(static_cast<int>(nout)); + __pbump(nout); __strmode_ |= __allocated; } *pptr() = static_cast<char>(__c); @@ -282,7 +282,7 @@ strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmod // min(pbase, newpos), newpos, epptr() __off = epptr() - newpos; setp(min(pbase(), newpos), epptr()); - pbump(static_cast<int>((epptr() - pbase()) - __off)); + __pbump((epptr() - pbase()) - __off); } __p = newoff; } @@ -312,7 +312,7 @@ strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which) // min(pbase, newpos), newpos, epptr() off_type temp = epptr() - newpos; setp(min(pbase(), newpos), epptr()); - pbump(static_cast<int>((epptr() - pbase()) - temp)); + __pbump((epptr() - pbase()) - temp); } __p = newoff; } diff --git a/src/support/runtime/exception_fallback.ipp b/src/support/runtime/exception_fallback.ipp index 69c06a9ce3a8..664e7f48c09a 100644 --- a/src/support/runtime/exception_fallback.ipp +++ b/src/support/runtime/exception_fallback.ipp @@ -20,13 +20,13 @@ _LIBCPP_SAFE_STATIC static std::unexpected_handler __unexpected_handler; unexpected_handler set_unexpected(unexpected_handler func) _NOEXCEPT { - return __sync_lock_test_and_set(&__unexpected_handler, func); + return __libcpp_atomic_exchange(&__unexpected_handler, func); } unexpected_handler get_unexpected() _NOEXCEPT { - return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0); + return __libcpp_atomic_load(&__unexpected_handler); } @@ -41,14 +41,13 @@ void unexpected() terminate_handler set_terminate(terminate_handler func) _NOEXCEPT { - return __sync_lock_test_and_set(&__terminate_handler, func); + return __libcpp_atomic_exchange(&__terminate_handler, func); } terminate_handler get_terminate() _NOEXCEPT { - return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0); - + return __libcpp_atomic_load(&__terminate_handler); } #ifndef __EMSCRIPTEN__ // We provide this in JS diff --git a/src/support/runtime/exception_msvc.ipp b/src/support/runtime/exception_msvc.ipp index 950ec0cebfe7..d5bf5b726ea5 100644 --- a/src/support/runtime/exception_msvc.ipp +++ b/src/support/runtime/exception_msvc.ipp @@ -14,12 +14,35 @@ #include <stdio.h> #include <stdlib.h> -#include <eh.h> -#include <corecrt_terminate.h> + +#if !defined(_ACRTIMP) +#define _ACRTIMP __declspec(dllimport) +#endif + +#if !defined(_VCRTIMP) +#define _VCRTIMP __declspec(dllimport) +#endif + +#if !defined(__CRTDECL) +#define __CRTDECL __cdecl +#endif + +extern "C" { +typedef void (__CRTDECL* terminate_handler)(); +_ACRTIMP terminate_handler __cdecl set_terminate( + terminate_handler _NewTerminateHandler) throw(); +_ACRTIMP terminate_handler __cdecl _get_terminate(); + +typedef void (__CRTDECL* unexpected_handler)(); +_VCRTIMP unexpected_handler __cdecl set_unexpected( + unexpected_handler _NewUnexpectedHandler) throw(); +_VCRTIMP unexpected_handler __cdecl _get_unexpected(); + +_VCRTIMP int __cdecl __uncaught_exceptions(); +} namespace std { -// libcxxrt provides implementations of these functions itself. unexpected_handler set_unexpected(unexpected_handler func) _NOEXCEPT { return ::set_unexpected(func); @@ -86,4 +109,82 @@ bad_array_length::what() const _NOEXCEPT return "bad_array_length"; } +bad_cast::bad_cast() _NOEXCEPT +{ +} + +bad_cast::~bad_cast() _NOEXCEPT +{ +} + +const char * +bad_cast::what() const _NOEXCEPT +{ + return "std::bad_cast"; +} + +bad_typeid::bad_typeid() _NOEXCEPT +{ +} + +bad_typeid::~bad_typeid() _NOEXCEPT +{ +} + +const char * +bad_typeid::what() const _NOEXCEPT +{ + return "std::bad_typeid"; +} + +#if defined(_LIBCPP_NO_VCRUNTIME) +exception::~exception() _NOEXCEPT +{ +} + +const char* exception::what() const _NOEXCEPT +{ + return "std::exception"; +} + + +bad_exception::~bad_exception() _NOEXCEPT +{ +} + +const char* bad_exception::what() const _NOEXCEPT +{ + return "std::bad_exception"; +} + + +bad_alloc::bad_alloc() _NOEXCEPT +{ +} + +bad_alloc::~bad_alloc() _NOEXCEPT +{ +} + +const char* +bad_alloc::what() const _NOEXCEPT +{ + return "std::bad_alloc"; +} + +bad_array_new_length::bad_array_new_length() _NOEXCEPT +{ +} + +bad_array_new_length::~bad_array_new_length() _NOEXCEPT +{ +} + +const char* +bad_array_new_length::what() const _NOEXCEPT +{ + return "bad_array_new_length"; +} +#endif // _LIBCPP_NO_VCRUNTIME + } // namespace std diff --git a/src/support/runtime/exception_pointer_msvc.ipp b/src/support/runtime/exception_pointer_msvc.ipp index eab5d30a9487..5ca7519a6001 100644 --- a/src/support/runtime/exception_pointer_msvc.ipp +++ b/src/support/runtime/exception_pointer_msvc.ipp @@ -10,26 +10,32 @@ #include <stdio.h> #include <stdlib.h> -#include <yvals.h> // for _CRTIMP2_PURE -_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCreate(_Out_ void*); -_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrDestroy(_Inout_ void*); -_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCopy(_Out_ void*, - _In_ const void*); +#if !defined(_CRTIMP2_PURE) +#define _CRTIMP2_PURE __declspec(dllimport) +#endif + +#if !defined(__CLRCALL_PURE_OR_CDECL) +#define __CLRCALL_PURE_OR_CDECL __cdecl +#endif + +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCreate(void*); +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrDestroy(void*); +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCopy(void*, + const void*); _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL -__ExceptionPtrAssign(_Inout_ void*, _In_ const void*); +__ExceptionPtrAssign(void*, const void*); _CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL -__ExceptionPtrCompare(_In_ const void*, _In_ const void*); +__ExceptionPtrCompare(const void*, const void*); _CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL -__ExceptionPtrToBool(_In_ const void*); -_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrSwap(_Inout_ void*, - _Inout_ void*); +__ExceptionPtrToBool(const void*); +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrSwap(void*, void*); _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL -__ExceptionPtrCurrentException(_Out_ void*); +__ExceptionPtrCurrentException(void*); [[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL -__ExceptionPtrRethrow(_In_ const void*); +__ExceptionPtrRethrow(const void*); _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL -__ExceptionPtrCopyException(_Inout_ void*, _In_ const void*, _In_ const void*); +__ExceptionPtrCopyException(void*, const void*, const void*); namespace std { diff --git a/src/support/runtime/new_handler_fallback.ipp b/src/support/runtime/new_handler_fallback.ipp index b7092d542d97..ec3f52354ca8 100644 --- a/src/support/runtime/new_handler_fallback.ipp +++ b/src/support/runtime/new_handler_fallback.ipp @@ -15,13 +15,13 @@ _LIBCPP_SAFE_STATIC static std::new_handler __new_handler; new_handler set_new_handler(new_handler handler) _NOEXCEPT { - return __sync_lock_test_and_set(&__new_handler, handler); + return __libcpp_atomic_exchange(&__new_handler, handler); } new_handler get_new_handler() _NOEXCEPT { - return __sync_fetch_and_add(&__new_handler, nullptr); + return __libcpp_atomic_load(&__new_handler); } } // namespace std diff --git a/src/support/win32/locale_win32.cpp b/src/support/win32/locale_win32.cpp index 13a6eaedacb2..fdca7efff067 100644 --- a/src/support/win32/locale_win32.cpp +++ b/src/support/win32/locale_win32.cpp @@ -18,21 +18,7 @@ using std::__libcpp_locale_guard; // FIXME: base currently unused. Needs manual work to construct the new locale locale_t newlocale( int mask, const char * locale, locale_t /*base*/ ) { - return _create_locale( mask, locale ); -} - -locale_t uselocale( locale_t newloc ) -{ - locale_t old_locale = _get_current_locale(); - if ( newloc == NULL ) - return old_locale; - // uselocale sets the thread's locale by definition, so unconditionally use thread-local locale - _configthreadlocale( _ENABLE_PER_THREAD_LOCALE ); - // uselocale sets all categories - // disable setting locale on Windows temporarily because the structure is opaque (PR31516) - //setlocale( LC_ALL, newloc->locinfo->lc_category[LC_ALL].locale ); - // uselocale returns the old locale_t - return old_locale; + return {_create_locale( LC_ALL, locale ), locale}; } decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l ) diff --git a/src/system_error.cpp b/src/system_error.cpp index 17f2c9a5ba79..72623ea6bc81 100644 --- a/src/system_error.cpp +++ b/src/system_error.cpp @@ -73,39 +73,59 @@ string do_strerror_r(int ev) { std::snprintf(buffer, strerror_buff_size, "unknown error %d", ev); return string(buffer); } -#elif defined(__linux__) && !defined(_LIBCPP_HAS_MUSL_LIBC) && \ - (!defined(__ANDROID__) || __ANDROID_API__ >= 23) -// GNU Extended version -string do_strerror_r(int ev) { - char buffer[strerror_buff_size]; - char* ret = ::strerror_r(ev, buffer, strerror_buff_size); - return string(ret); -} #else -// POSIX version + +// Only one of the two following functions will be used, depending on +// the return type of strerror_r: + +// For the GNU variant, a char* return value: +__attribute__((unused)) const char * +handle_strerror_r_return(char *strerror_return, char *buffer) { + // GNU always returns a string pointer in its return value. The + // string might point to either the input buffer, or a static + // buffer, but we don't care which. + return strerror_return; +} + +// For the POSIX variant: an int return value. +__attribute__((unused)) const char * +handle_strerror_r_return(int strerror_return, char *buffer) { + // The POSIX variant either: + // - fills in the provided buffer and returns 0 + // - returns a positive error value, or + // - returns -1 and fills in errno with an error value. + if (strerror_return == 0) + return buffer; + + // Only handle EINVAL. Other errors abort. + int new_errno = strerror_return == -1 ? errno : strerror_return; + if (new_errno == EINVAL) + return ""; + + _LIBCPP_ASSERT(new_errno == ERANGE, "unexpected error from ::strerror_r"); + // FIXME maybe? 'strerror_buff_size' is likely to exceed the + // maximum error size so ERANGE shouldn't be returned. + std::abort(); +} + +// This function handles both GNU and POSIX variants, dispatching to +// one of the two above functions. string do_strerror_r(int ev) { char buffer[strerror_buff_size]; + // Preserve errno around the call. (The C++ standard requires that + // system_error functions not modify errno). const int old_errno = errno; - int ret; - if ((ret = ::strerror_r(ev, buffer, strerror_buff_size)) != 0) { - // If `ret == -1` then the error is specified using `errno`, otherwise - // `ret` represents the error. - const int new_errno = ret == -1 ? errno : ret; - errno = old_errno; - if (new_errno == EINVAL) { - std::snprintf(buffer, strerror_buff_size, "Unknown error %d", ev); - return string(buffer); - } else { - _LIBCPP_ASSERT(new_errno == ERANGE, "unexpected error from ::strerr_r"); - // FIXME maybe? 'strerror_buff_size' is likely to exceed the - // maximum error size so ERANGE shouldn't be returned. - std::abort(); - } + const char *error_message = handle_strerror_r_return( + ::strerror_r(ev, buffer, strerror_buff_size), buffer); + // If we didn't get any message, print one now. + if (!error_message[0]) { + std::snprintf(buffer, strerror_buff_size, "Unknown error %d", ev); + error_message = buffer; } - return string(buffer); + errno = old_errno; + return string(error_message); } #endif - } // end namespace #endif diff --git a/src/typeinfo.cpp b/src/typeinfo.cpp index 02778f368704..0cb193b77d9e 100644 --- a/src/typeinfo.cpp +++ b/src/typeinfo.cpp @@ -9,11 +9,48 @@ #include "typeinfo" +#if defined(_LIBCPP_ABI_MICROSOFT) +#include <string.h> + +int std::type_info::__compare(const type_info &__rhs) const _NOEXCEPT { + if (&__data == &__rhs.__data) + return 0; + return strcmp(&__data.__decorated_name[1], &__rhs.__data.__decorated_name[1]); +} + +const char *std::type_info::name() const _NOEXCEPT { + // TODO(compnerd) cache demangled &__data.__decorated_name[1] + return &__data.__decorated_name[1]; +} + +size_t std::type_info::hash_code() const _NOEXCEPT { +#if defined(_WIN64) + constexpr size_t fnv_offset_basis = 14695981039346656037ull; + constexpr size_t fnv_prime = 10995116282110ull; +#else + constexpr size_t fnv_offset_basis = 2166136261ull; + constexpr size_t fnv_prime = 16777619ull; +#endif + + size_t value = fnv_offset_basis; + for (const char* c = &__data.__decorated_name[1]; *c; ++c) { + value ^= static_cast<size_t>(static_cast<unsigned char>(*c)); + value *= fnv_prime; + } + +#if defined(_WIN64) + value ^= value >> 32; +#endif + + return value; +} +#endif // _LIBCPP_ABI_MICROSOFT + // FIXME: Remove __APPLE__ default here once buildit is gone. -#if (!defined(_LIBCPP_ABI_MICROSOFT) && !defined(LIBCXX_BUILDING_LIBCXXABI) && \ - !defined(LIBCXXRT) && !defined(__GLIBCXX__) && \ - !defined(__APPLE__)) || \ - defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) // FIXME: remove this configuration. +// FIXME: Remove the _LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY configuration. +#if (!defined(LIBCXX_BUILDING_LIBCXXABI) && !defined(LIBCXXRT) && \ + !defined(__GLIBCXX__) && !defined(__APPLE__)) || \ + defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) std::type_info::~type_info() { } |