summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/exception.cpp1
-rw-r--r--src/experimental/filesystem/directory_iterator.cpp37
-rw-r--r--src/experimental/filesystem/operations.cpp22
-rw-r--r--src/include/atomic_support.h19
-rw-r--r--src/include/config_elast.h2
-rw-r--r--src/include/refstring.h9
-rw-r--r--src/iostream.cpp20
-rw-r--r--src/locale.cpp3
-rw-r--r--src/new.cpp10
-rw-r--r--src/random.cpp29
-rw-r--r--src/strstream.cpp6
-rw-r--r--src/support/runtime/exception_fallback.ipp9
-rw-r--r--src/support/runtime/exception_msvc.ipp107
-rw-r--r--src/support/runtime/exception_pointer_msvc.ipp32
-rw-r--r--src/support/runtime/new_handler_fallback.ipp4
-rw-r--r--src/support/win32/locale_win32.cpp16
-rw-r--r--src/system_error.cpp72
-rw-r--r--src/typeinfo.cpp45
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()
{
}