diff options
Diffstat (limited to 'contrib/llvm-project/libcxx/src')
19 files changed, 816 insertions, 344 deletions
diff --git a/contrib/llvm-project/libcxx/src/atomic.cpp b/contrib/llvm-project/libcxx/src/atomic.cpp index 65d4837bb4a7..9ae1fb5199bf 100644 --- a/contrib/llvm-project/libcxx/src/atomic.cpp +++ b/contrib/llvm-project/libcxx/src/atomic.cpp @@ -13,14 +13,18 @@ #include <atomic> #include <functional> -#include <iostream> - #ifdef __linux__ #include <unistd.h> #include <linux/futex.h> #include <sys/syscall.h> +// libc++ uses SYS_futex as a universal syscall name. However, on 32 bit architectures +// with a 64 bit time_t, we need to specify SYS_futex_time64. +#if !defined(SYS_futex) && defined(SYS_futex_time64) +# define SYS_futex SYS_futex_time64 +#endif + #else // <- Add other operating systems here // Baseline needs no new headers diff --git a/contrib/llvm-project/libcxx/src/barrier.cpp b/contrib/llvm-project/libcxx/src/barrier.cpp index c5e33cbba3bd..9ee476993b81 100644 --- a/contrib/llvm-project/libcxx/src/barrier.cpp +++ b/contrib/llvm-project/libcxx/src/barrier.cpp @@ -26,21 +26,15 @@ public: } __tickets[64]; }; - ptrdiff_t& __expected; - unique_ptr<char[]> __state_allocation; - __state_t* __state; + ptrdiff_t& __expected; + unique_ptr<__state_t[]> __state; _LIBCPP_HIDDEN __barrier_algorithm_base(ptrdiff_t& __expected) : __expected(__expected) { size_t const __count = (__expected + 1) >> 1; - size_t const __size = sizeof(__state_t) * __count; - size_t __allocation_size = __size + alignof(__state_t); - __state_allocation = unique_ptr<char[]>(new char[__allocation_size]); - void* __allocation = __state_allocation.get(); - void* const __state_ = align(alignof(__state_t), __size, __allocation, __allocation_size); - __state = new (__state_) __barrier_algorithm_base::__state_t[__count]; + __state = unique_ptr<__state_t[]>(new __state_t[__count]); } _LIBCPP_HIDDEN bool __arrive(__barrier_phase_t __old_phase) diff --git a/contrib/llvm-project/libcxx/src/chrono.cpp b/contrib/llvm-project/libcxx/src/chrono.cpp index f0a5d50ddf77..085fbfde26c1 100644 --- a/contrib/llvm-project/libcxx/src/chrono.cpp +++ b/contrib/llvm-project/libcxx/src/chrono.cpp @@ -13,11 +13,15 @@ #include "include/apple_availability.h" #if __has_include(<unistd.h>) -#include <unistd.h> +# include <unistd.h> +#endif + +#if __has_include(<sys/time.h>) +# include <sys/time.h> // for gettimeofday and timeval #endif #if !defined(__APPLE__) && _POSIX_TIMERS > 0 -#define _LIBCPP_USE_CLOCK_GETTIME +# define _LIBCPP_USE_CLOCK_GETTIME #endif #if defined(_LIBCPP_WIN32API) @@ -27,12 +31,12 @@ # if _WIN32_WINNT >= _WIN32_WINNT_WIN8 # include <winapifamily.h> # endif -#else -# if !defined(CLOCK_REALTIME) -# include <sys/time.h> // for gettimeofday and timeval -# endif // !defined(CLOCK_REALTIME) #endif // defined(_LIBCPP_WIN32API) +#if __has_include(<mach/mach_time.h>) +# include <mach/mach_time.h> +#endif + #if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB) # pragma comment(lib, "rt") #endif @@ -42,14 +46,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace chrono { +// // system_clock +// -const bool system_clock::is_steady; - -system_clock::time_point -system_clock::now() _NOEXCEPT -{ #if defined(_LIBCPP_WIN32API) + +static system_clock::time_point __libcpp_system_clock_now() { // FILETIME is in 100ns units using filetime_duration = _VSTD::chrono::duration<__int64, @@ -60,31 +63,42 @@ system_clock::now() _NOEXCEPT static _LIBCPP_CONSTEXPR const seconds nt_to_unix_epoch{11644473600}; FILETIME ft; -#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) GetSystemTimePreciseAsFileTime(&ft); #else GetSystemTimeAsFileTime(&ft); #endif -#else - GetSystemTimeAsFileTime(&ft); -#endif filetime_duration d{(static_cast<__int64>(ft.dwHighDateTime) << 32) | static_cast<__int64>(ft.dwLowDateTime)}; - return time_point(duration_cast<duration>(d - nt_to_unix_epoch)); -#else -#if defined(CLOCK_REALTIME) + return system_clock::time_point(duration_cast<system_clock::duration>(d - nt_to_unix_epoch)); +} + +#elif defined(CLOCK_REALTIME) && defined(_LIBCPP_USE_CLOCK_GETTIME) + +static system_clock::time_point __libcpp_system_clock_now() { 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)); + return system_clock::time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000)); +} + #else + +static system_clock::time_point __libcpp_system_clock_now() { timeval tv; gettimeofday(&tv, 0); - return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); -#endif // CLOCK_REALTIME + return system_clock::time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); +} + #endif + +const bool system_clock::is_steady; + +system_clock::time_point +system_clock::now() _NOEXCEPT +{ + return __libcpp_system_clock_now(); } time_t @@ -99,35 +113,85 @@ system_clock::from_time_t(time_t t) _NOEXCEPT return system_clock::time_point(seconds(t)); } -#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; +#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK #if defined(__APPLE__) -#if !defined(CLOCK_MONOTONIC_RAW) -# error "Building libc++ on Apple platforms requires CLOCK_MONOTONIC_RAW" +// TODO(ldionne): +// This old implementation of steady_clock is retained until Chrome drops supports +// for macOS < 10.12. The issue is that they link libc++ statically into their +// application, which means that libc++ must support being built for such deployment +// targets. See https://llvm.org/D74489 for details. +#if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000) +# define _LIBCPP_USE_OLD_MACH_ABSOLUTE_TIME #endif +#if defined(_LIBCPP_USE_OLD_MACH_ABSOLUTE_TIME) + +// 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 +// to the Gregorian calendar. It's main use is as a high resolution timer. + +// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize +// for that case as an optimization. + +static steady_clock::rep steady_simplified() { + return static_cast<steady_clock::rep>(mach_absolute_time()); +} +static double compute_steady_factor() { + mach_timebase_info_data_t MachInfo; + mach_timebase_info(&MachInfo); + return static_cast<double>(MachInfo.numer) / MachInfo.denom; +} + +static steady_clock::rep steady_full() { + static const double factor = compute_steady_factor(); + return static_cast<steady_clock::rep>(mach_absolute_time() * factor); +} + +typedef steady_clock::rep (*FP)(); + +static FP init_steady_clock() { + mach_timebase_info_data_t MachInfo; + mach_timebase_info(&MachInfo); + if (MachInfo.numer == MachInfo.denom) + return &steady_simplified; + return &steady_full; +} + +static steady_clock::time_point __libcpp_steady_clock_now() { + static FP fp = init_steady_clock(); + return steady_clock::time_point(steady_clock::duration(fp())); +} + +#else // vvvvv default behavior for Apple platforms vvvvv + // On Apple platforms, only CLOCK_UPTIME_RAW, CLOCK_MONOTONIC_RAW or // mach_absolute_time are able to time functions in the nanosecond range. // Furthermore, only CLOCK_MONOTONIC_RAW is truly monotonic, because it // also counts cycles when the system is asleep. Thus, it is the only // acceptable implementation of steady_clock. -steady_clock::time_point -steady_clock::now() _NOEXCEPT -{ +static steady_clock::time_point __libcpp_steady_clock_now() { struct timespec tp; if (0 != clock_gettime(CLOCK_MONOTONIC_RAW, &tp)) __throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC_RAW) failed"); - return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); + return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); } +#endif + #elif defined(_LIBCPP_WIN32API) // https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx says: @@ -138,36 +202,43 @@ steady_clock::now() _NOEXCEPT static LARGE_INTEGER __QueryPerformanceFrequency() { - LARGE_INTEGER val; - (void) QueryPerformanceFrequency(&val); - return val; + LARGE_INTEGER val; + (void) QueryPerformanceFrequency(&val); + return val; } -steady_clock::time_point -steady_clock::now() _NOEXCEPT -{ +static steady_clock::time_point __libcpp_steady_clock_now() { static const LARGE_INTEGER freq = __QueryPerformanceFrequency(); LARGE_INTEGER counter; (void) QueryPerformanceCounter(&counter); - return time_point(duration(counter.QuadPart * nano::den / freq.QuadPart)); + auto seconds = counter.QuadPart / freq.QuadPart; + auto fractions = counter.QuadPart % freq.QuadPart; + auto dur = seconds * nano::den + fractions * nano::den / freq.QuadPart; + return steady_clock::time_point(steady_clock::duration(dur)); } #elif defined(CLOCK_MONOTONIC) -steady_clock::time_point -steady_clock::now() _NOEXCEPT -{ +static steady_clock::time_point __libcpp_steady_clock_now() { 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)); + return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); } #else -# error "Monotonic clock not implemented" +# error "Monotonic clock not implemented on this platform" #endif +const bool steady_clock::is_steady; + +steady_clock::time_point +steady_clock::now() _NOEXCEPT +{ + return __libcpp_steady_clock_now(); +} + #endif // !_LIBCPP_HAS_NO_MONOTONIC_CLOCK } diff --git a/contrib/llvm-project/libcxx/src/experimental/memory_resource.cpp b/contrib/llvm-project/libcxx/src/experimental/memory_resource.cpp index 68c5bc99cc72..1304ef3df78f 100644 --- a/contrib/llvm-project/libcxx/src/experimental/memory_resource.cpp +++ b/contrib/llvm-project/libcxx/src/experimental/memory_resource.cpp @@ -76,16 +76,6 @@ union ResourceInitHelper { ~ResourceInitHelper() {} }; -// Detect if the init_priority attribute is supported. -#if (defined(_LIBCPP_COMPILER_GCC) && defined(__APPLE__)) \ - || defined(_LIBCPP_COMPILER_MSVC) -// GCC on Apple doesn't support the init priority attribute, -// and MSVC doesn't support any GCC attributes. -# define _LIBCPP_INIT_PRIORITY_MAX -#else -# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((init_priority(101))) -#endif - // When compiled in C++14 this initialization should be a constant expression. // Only in C++11 is "init_priority" needed to ensure initialization order. #if _LIBCPP_STD_VER > 11 diff --git a/contrib/llvm-project/libcxx/src/filesystem/directory_iterator.cpp b/contrib/llvm-project/libcxx/src/filesystem/directory_iterator.cpp index e8941b3494b3..2721dea5c98f 100644 --- a/contrib/llvm-project/libcxx/src/filesystem/directory_iterator.cpp +++ b/contrib/llvm-project/libcxx/src/filesystem/directory_iterator.cpp @@ -10,6 +10,7 @@ #include "__config" #if defined(_LIBCPP_WIN32API) #define WIN32_LEAN_AND_MEAN +#define NOMINMAX #include <windows.h> #else #include <dirent.h> @@ -72,16 +73,20 @@ static pair<string_view, file_type> posix_readdir(DIR* dir_stream, } } #else +// defined(_LIBCPP_WIN32API) -static file_type get_file_type(const WIN32_FIND_DATA& data) { - //auto attrs = data.dwFileAttributes; - // FIXME(EricWF) - return file_type::unknown; +static file_type get_file_type(const WIN32_FIND_DATAW& data) { + if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && + data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) + return file_type::symlink; + if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + return file_type::directory; + return file_type::regular; } -static uintmax_t get_file_size(const WIN32_FIND_DATA& data) { - return (data.nFileSizeHigh * (MAXDWORD + 1)) + data.nFileSizeLow; +static uintmax_t get_file_size(const WIN32_FIND_DATAW& data) { + return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow; } -static file_time_type get_write_time(const WIN32_FIND_DATA& data) { +static file_time_type get_write_time(const WIN32_FIND_DATAW& data) { ULARGE_INTEGER tmp; const FILETIME& time = data.ftLastWriteTime; tmp.u.LowPart = time.dwLowDateTime; @@ -110,15 +115,21 @@ public: __dir_stream(const path& root, directory_options opts, error_code& ec) : __stream_(INVALID_HANDLE_VALUE), __root_(root) { - __stream_ = ::FindFirstFile(root.c_str(), &__data_); + if (root.native().empty()) { + ec = make_error_code(errc::no_such_file_or_directory); + return; + } + __stream_ = ::FindFirstFileW((root / "*").c_str(), &__data_); if (__stream_ == INVALID_HANDLE_VALUE) { - ec = error_code(::GetLastError(), generic_category()); + ec = detail::make_windows_error(GetLastError()); const bool ignore_permission_denied = bool(opts & directory_options::skip_permission_denied); if (ignore_permission_denied && ec.value() == ERROR_ACCESS_DENIED) ec.clear(); return; } + if (!assign()) + advance(ec); } ~__dir_stream() noexcept { @@ -130,35 +141,39 @@ public: bool good() const noexcept { return __stream_ != INVALID_HANDLE_VALUE; } bool advance(error_code& ec) { - while (::FindNextFile(__stream_, &__data_)) { - if (!strcmp(__data_.cFileName, ".") || strcmp(__data_.cFileName, "..")) - continue; - // FIXME: Cache more of this - //directory_entry::__cached_data cdata; - //cdata.__type_ = get_file_type(__data_); - //cdata.__size_ = get_file_size(__data_); - //cdata.__write_time_ = get_write_time(__data_); - __entry_.__assign_iter_entry( - __root_ / __data_.cFileName, - directory_entry::__create_iter_result(detail::get_file_type(__data))); - return true; + while (::FindNextFileW(__stream_, &__data_)) { + if (assign()) + return true; } - ec = error_code(::GetLastError(), generic_category()); close(); return false; } + bool assign() { + if (!wcscmp(__data_.cFileName, L".") || !wcscmp(__data_.cFileName, L"..")) + return false; + // FIXME: Cache more of this + //directory_entry::__cached_data cdata; + //cdata.__type_ = get_file_type(__data_); + //cdata.__size_ = get_file_size(__data_); + //cdata.__write_time_ = get_write_time(__data_); + __entry_.__assign_iter_entry( + __root_ / __data_.cFileName, + directory_entry::__create_iter_result(detail::get_file_type(__data_))); + return true; + } + private: error_code close() noexcept { error_code ec; if (!::FindClose(__stream_)) - ec = error_code(::GetLastError(), generic_category()); + ec = detail::make_windows_error(GetLastError()); __stream_ = INVALID_HANDLE_VALUE; return ec; } HANDLE __stream_{INVALID_HANDLE_VALUE}; - WIN32_FIND_DATA __data_; + WIN32_FIND_DATAW __data_; public: path __root_; diff --git a/contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h b/contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h index fe5c42f5e6d0..e0fdbccf96b1 100644 --- a/contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h +++ b/contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h @@ -13,14 +13,17 @@ #include "filesystem" #include "array" #include "chrono" -#include "cstdlib" #include "climits" - -#include <unistd.h> -#include <sys/stat.h> -#include <sys/statvfs.h> -#include <sys/time.h> // for ::utimes as used in __last_write_time -#include <fcntl.h> /* values for fchmodat */ +#include "cstdlib" +#include "ctime" + +#if !defined(_LIBCPP_WIN32API) +# include <unistd.h> +# include <sys/stat.h> +# include <sys/statvfs.h> +# include <sys/time.h> // for ::utimes as used in __last_write_time +# include <fcntl.h> /* values for fchmodat */ +#endif #include "../include/apple_availability.h" @@ -37,9 +40,21 @@ #pragma GCC diagnostic ignored "-Wunused-function" #endif +#if defined(_LIBCPP_WIN32API) +#define PS(x) (L##x) +#else +#define PS(x) (x) +#endif + _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM namespace detail { + +#if defined(_LIBCPP_WIN32API) +// Non anonymous, to allow access from two translation units. +errc __win_err_to_errc(int err); +#endif + namespace { static string format_string_imp(const char* msg, ...) { @@ -47,7 +62,7 @@ static string format_string_imp(const char* msg, ...) { struct GuardVAList { va_list& target; bool active = true; - GuardVAList(va_list& target) : target(target), active(true) {} + GuardVAList(va_list& tgt) : target(tgt), active(true) {} void clear() { if (active) va_end(target); @@ -93,8 +108,8 @@ static string format_string_imp(const char* msg, ...) { return result; } -const char* unwrap(string const& s) { return s.c_str(); } -const char* unwrap(path const& p) { return p.native().c_str(); } +const path::value_type* unwrap(path::string_type const& s) { return s.c_str(); } +const path::value_type* unwrap(path const& p) { return p.native().c_str(); } template <class Arg> Arg const& unwrap(Arg const& a) { static_assert(!is_class<Arg>::value, "cannot pass class here"); @@ -111,6 +126,12 @@ error_code capture_errno() { return error_code(errno, generic_category()); } +#if defined(_LIBCPP_WIN32API) +error_code make_windows_error(int err) { + return make_error_code(__win_err_to_errc(err)); +} +#endif + template <class T> T error_value(); template <> @@ -119,6 +140,12 @@ template <> bool error_value<bool>() { return false; } +#if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__ +template <> +size_t error_value<size_t>() { + return size_t(-1); +} +#endif template <> uintmax_t error_value<uintmax_t>() { return uintmax_t(-1); @@ -134,50 +161,50 @@ path error_value<path>() { template <class T> struct ErrorHandler { - const char* func_name; - error_code* ec = nullptr; - const path* p1 = nullptr; - const path* p2 = nullptr; + const char* func_name_; + error_code* ec_ = nullptr; + const path* p1_ = nullptr; + const path* p2_ = nullptr; ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr, const path* p2 = nullptr) - : func_name(fname), ec(ec), p1(p1), p2(p2) { - if (ec) - ec->clear(); + : func_name_(fname), ec_(ec), p1_(p1), p2_(p2) { + if (ec_) + ec_->clear(); } - T report(const error_code& m_ec) const { - if (ec) { - *ec = m_ec; + T report(const error_code& ec) const { + if (ec_) { + *ec_ = ec; return error_value<T>(); } - string what = string("in ") + func_name; - switch (bool(p1) + bool(p2)) { + string what = string("in ") + func_name_; + switch (bool(p1_) + bool(p2_)) { case 0: - __throw_filesystem_error(what, m_ec); + __throw_filesystem_error(what, ec); case 1: - __throw_filesystem_error(what, *p1, m_ec); + __throw_filesystem_error(what, *p1_, ec); case 2: - __throw_filesystem_error(what, *p1, *p2, m_ec); + __throw_filesystem_error(what, *p1_, *p2_, ec); } _LIBCPP_UNREACHABLE(); } template <class... Args> - T report(const error_code& m_ec, const char* msg, Args const&... args) const { - if (ec) { - *ec = m_ec; + T report(const error_code& ec, const char* msg, Args const&... args) const { + if (ec_) { + *ec_ = ec; return error_value<T>(); } string what = - string("in ") + func_name + ": " + format_string(msg, args...); - switch (bool(p1) + bool(p2)) { + string("in ") + func_name_ + ": " + format_string(msg, args...); + switch (bool(p1_) + bool(p2_)) { case 0: - __throw_filesystem_error(what, m_ec); + __throw_filesystem_error(what, ec); case 1: - __throw_filesystem_error(what, *p1, m_ec); + __throw_filesystem_error(what, *p1_, ec); case 2: - __throw_filesystem_error(what, *p1, *p2, m_ec); + __throw_filesystem_error(what, *p1_, *p2_, ec); } _LIBCPP_UNREACHABLE(); } @@ -197,8 +224,9 @@ private: using chrono::duration; using chrono::duration_cast; -using TimeSpec = struct ::timespec; -using StatT = struct ::stat; +using TimeSpec = struct timespec; +using TimeVal = struct timeval; +using StatT = struct stat; template <class FileTimeT, class TimeT, bool IsFloat = is_floating_point<typename FileTimeT::rep>::value> @@ -380,26 +408,38 @@ public: using fs_time = time_util<file_time_type, time_t, TimeSpec>; #if defined(__APPLE__) -TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; } -TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; } +inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; } +inline TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; } +#elif defined(__MVS__) +inline TimeSpec extract_mtime(StatT const& st) { + TimeSpec TS = {st.st_mtime, 0}; + return TS; +} +inline TimeSpec extract_atime(StatT const& st) { + TimeSpec TS = {st.st_atime, 0}; + return TS; +} #else -TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; } -TimeSpec extract_atime(StatT const& st) { return st.st_atim; } +inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; } +inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; } #endif -// allow the utimes implementation to compile even it we're not going -// to use it. - -bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS, - error_code& ec) { +inline TimeVal make_timeval(TimeSpec const& ts) { using namespace chrono; auto Convert = [](long nsec) { - using int_type = decltype(std::declval< ::timeval>().tv_usec); + using int_type = decltype(std::declval<TimeVal>().tv_usec); auto dur = duration_cast<microseconds>(nanoseconds(nsec)).count(); return static_cast<int_type>(dur); }; - struct ::timeval ConvertedTS[2] = {{TS[0].tv_sec, Convert(TS[0].tv_nsec)}, - {TS[1].tv_sec, Convert(TS[1].tv_nsec)}}; + TimeVal TV = {}; + TV.tv_sec = ts.tv_sec; + TV.tv_usec = Convert(ts.tv_nsec); + return TV; +} + +inline bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS, + error_code& ec) { + TimeVal ConvertedTS[2] = {make_timeval(TS[0]), make_timeval(TS[1])}; if (::utimes(p.c_str(), ConvertedTS) == -1) { ec = capture_errno(); return true; diff --git a/contrib/llvm-project/libcxx/src/filesystem/operations.cpp b/contrib/llvm-project/libcxx/src/filesystem/operations.cpp index 5c98671feeed..50a895dc2fae 100644 --- a/contrib/llvm-project/libcxx/src/filesystem/operations.cpp +++ b/contrib/llvm-project/libcxx/src/filesystem/operations.cpp @@ -9,8 +9,6 @@ #include "filesystem" #include "array" #include "iterator" -#include "fstream" -#include "random" /* for unique_path */ #include "string_view" #include "type_traits" #include "vector" @@ -19,40 +17,51 @@ #include "filesystem_common.h" -#include <unistd.h> -#include <sys/stat.h> -#include <sys/statvfs.h> +#if defined(_LIBCPP_WIN32API) +# define WIN32_LEAN_AND_MEAN +# define NOMINMAX +# include <windows.h> +#else +# include <unistd.h> +# include <sys/stat.h> +# include <sys/statvfs.h> +#endif #include <time.h> #include <fcntl.h> /* values for fchmodat */ -#if defined(__linux__) -#include <linux/version.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) -#include <sys/sendfile.h> -#define _LIBCPP_USE_SENDFILE -#endif +#if __has_include(<sys/sendfile.h>) +# include <sys/sendfile.h> +# define _LIBCPP_FILESYSTEM_USE_SENDFILE #elif defined(__APPLE__) || __has_include(<copyfile.h>) -#include <copyfile.h> -#define _LIBCPP_USE_COPYFILE +# include <copyfile.h> +# define _LIBCPP_FILESYSTEM_USE_COPYFILE +#else +# include "fstream" +# define _LIBCPP_FILESYSTEM_USE_FSTREAM #endif #if !defined(CLOCK_REALTIME) -#include <sys/time.h> // for gettimeofday and timeval -#endif // !defined(CLOCK_REALTIME) - -#if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB) -#pragma comment(lib, "rt") +# include <sys/time.h> // for gettimeofday and timeval #endif -#if defined(_LIBCPP_COMPILER_GCC) -#if _GNUC_VER < 500 -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#endif +#if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB) +# pragma comment(lib, "rt") #endif _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM namespace { + +bool isSeparator(path::value_type C) { + if (C == '/') + return true; +#if defined(_LIBCPP_WIN32API) + if (C == '\\') + return true; +#endif + return false; +} + namespace parser { using string_view_t = path::__string_view; @@ -179,11 +188,14 @@ public: switch (State) { case PS_BeforeBegin: case PS_AtEnd: - return ""; + return PS(""); case PS_InRootDir: - return "/"; + if (RawEntry[0] == '\\') + return PS("\\"); + else + return PS("/"); case PS_InTrailingSep: - return ""; + return PS(""); case PS_InRootName: case PS_InFilenames: return RawEntry; @@ -270,29 +282,29 @@ private: } PosPtr consumeSeparator(PosPtr P, PosPtr End) const noexcept { - if (P == End || *P != '/') + if (P == End || !isSeparator(*P)) return nullptr; const int Inc = P < End ? 1 : -1; P += Inc; - while (P != End && *P == '/') + while (P != End && isSeparator(*P)) P += Inc; return P; } PosPtr consumeName(PosPtr P, PosPtr End) const noexcept { - if (P == End || *P == '/') + if (P == End || isSeparator(*P)) return nullptr; const int Inc = P < End ? 1 : -1; P += Inc; - while (P != End && *P != '/') + while (P != End && !isSeparator(*P)) P += Inc; return P; } }; string_view_pair separate_filename(string_view_t const& s) { - if (s == "." || s == ".." || s.empty()) - return string_view_pair{s, ""}; + if (s == PS(".") || s == PS("..") || s.empty()) + return string_view_pair{s, PS("")}; auto pos = s.find_last_of('.'); if (pos == string_view_t::npos || pos == 0) return string_view_pair{s, string_view_t{}}; @@ -308,6 +320,73 @@ string_view_t createView(PosPtr S, PosPtr E) noexcept { // POSIX HELPERS +#if defined(_LIBCPP_WIN32API) +namespace detail { + +errc __win_err_to_errc(int err) { + constexpr struct { + DWORD win; + errc errc; + } win_error_mapping[] = { + {ERROR_ACCESS_DENIED, errc::permission_denied}, + {ERROR_ALREADY_EXISTS, errc::file_exists}, + {ERROR_BAD_NETPATH, errc::no_such_file_or_directory}, + {ERROR_BAD_UNIT, errc::no_such_device}, + {ERROR_BROKEN_PIPE, errc::broken_pipe}, + {ERROR_BUFFER_OVERFLOW, errc::filename_too_long}, + {ERROR_BUSY, errc::device_or_resource_busy}, + {ERROR_BUSY_DRIVE, errc::device_or_resource_busy}, + {ERROR_CANNOT_MAKE, errc::permission_denied}, + {ERROR_CANTOPEN, errc::io_error}, + {ERROR_CANTREAD, errc::io_error}, + {ERROR_CANTWRITE, errc::io_error}, + {ERROR_CURRENT_DIRECTORY, errc::permission_denied}, + {ERROR_DEV_NOT_EXIST, errc::no_such_device}, + {ERROR_DEVICE_IN_USE, errc::device_or_resource_busy}, + {ERROR_DIR_NOT_EMPTY, errc::directory_not_empty}, + {ERROR_DIRECTORY, errc::invalid_argument}, + {ERROR_DISK_FULL, errc::no_space_on_device}, + {ERROR_FILE_EXISTS, errc::file_exists}, + {ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory}, + {ERROR_HANDLE_DISK_FULL, errc::no_space_on_device}, + {ERROR_INVALID_ACCESS, errc::permission_denied}, + {ERROR_INVALID_DRIVE, errc::no_such_device}, + {ERROR_INVALID_FUNCTION, errc::function_not_supported}, + {ERROR_INVALID_HANDLE, errc::invalid_argument}, + {ERROR_INVALID_NAME, errc::no_such_file_or_directory}, + {ERROR_INVALID_PARAMETER, errc::invalid_argument}, + {ERROR_LOCK_VIOLATION, errc::no_lock_available}, + {ERROR_LOCKED, errc::no_lock_available}, + {ERROR_NEGATIVE_SEEK, errc::invalid_argument}, + {ERROR_NOACCESS, errc::permission_denied}, + {ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory}, + {ERROR_NOT_READY, errc::resource_unavailable_try_again}, + {ERROR_NOT_SAME_DEVICE, errc::cross_device_link}, + {ERROR_NOT_SUPPORTED, errc::not_supported}, + {ERROR_OPEN_FAILED, errc::io_error}, + {ERROR_OPEN_FILES, errc::device_or_resource_busy}, + {ERROR_OPERATION_ABORTED, errc::operation_canceled}, + {ERROR_OUTOFMEMORY, errc::not_enough_memory}, + {ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory}, + {ERROR_READ_FAULT, errc::io_error}, + {ERROR_REPARSE_TAG_INVALID, errc::invalid_argument}, + {ERROR_RETRY, errc::resource_unavailable_try_again}, + {ERROR_SEEK, errc::io_error}, + {ERROR_SHARING_VIOLATION, errc::permission_denied}, + {ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open}, + {ERROR_WRITE_FAULT, errc::io_error}, + {ERROR_WRITE_PROTECT, errc::permission_denied}, + }; + + for (const auto &pair : win_error_mapping) + if (pair.win == static_cast<DWORD>(err)) + return pair.errc; + return errc::invalid_argument; +} + +} // namespace detail +#endif + namespace detail { namespace { @@ -503,19 +582,25 @@ _FilesystemClock::time_point _FilesystemClock::now() noexcept { filesystem_error::~filesystem_error() {} +#if defined(_LIBCPP_WIN32API) +#define PS_FMT "%ls" +#else +#define PS_FMT "%s" +#endif + void filesystem_error::__create_what(int __num_paths) { const char* derived_what = system_error::what(); __storage_->__what_ = [&]() -> string { - const char* p1 = path1().native().empty() ? "\"\"" : path1().c_str(); - const char* p2 = path2().native().empty() ? "\"\"" : path2().c_str(); + const path::value_type* p1 = path1().native().empty() ? PS("\"\"") : path1().c_str(); + const path::value_type* p2 = path2().native().empty() ? PS("\"\"") : path2().c_str(); switch (__num_paths) { default: return detail::format_string("filesystem error: %s", derived_what); case 1: - return detail::format_string("filesystem error: %s [%s]", derived_what, + return detail::format_string("filesystem error: %s [" PS_FMT "]", derived_what, p1); case 2: - return detail::format_string("filesystem error: %s [%s] [%s]", + return detail::format_string("filesystem error: %s [" PS_FMT "] [" PS_FMT "]", derived_what, p1, p2); } }(); @@ -542,14 +627,18 @@ path __canonical(path const& orig_p, error_code* ec) { ErrorHandler<path> err("canonical", ec, &orig_p, &cwd); path p = __do_absolute(orig_p, &cwd, ec); -#if _POSIX_VERSION >= 200112 +#if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112 std::unique_ptr<char, decltype(&::free)> hold(::realpath(p.c_str(), nullptr), &::free); if (hold.get() == nullptr) return err.report(capture_errno()); return {hold.get()}; #else - char buff[PATH_MAX + 1]; + #if defined(__MVS__) && !defined(PATH_MAX) + char buff[ _XOPEN_PATH_MAX + 1 ]; + #else + char buff[PATH_MAX + 1]; + #endif char* ret; if ((ret = ::realpath(p.c_str(), buff)) == nullptr) return err.report(capture_errno()); @@ -646,96 +735,83 @@ void __copy(const path& from, const path& to, copy_options options, namespace detail { namespace { -#ifdef _LIBCPP_USE_SENDFILE -bool copy_file_impl_sendfile(FileDescriptor& read_fd, FileDescriptor& write_fd, - error_code& ec) { - - size_t count = read_fd.get_stat().st_size; - do { - ssize_t res; - if ((res = ::sendfile(write_fd.fd, read_fd.fd, nullptr, count)) == -1) { - ec = capture_errno(); - return false; - } - count -= res; - } while (count > 0); - - ec.clear(); +#if defined(_LIBCPP_FILESYSTEM_USE_SENDFILE) + bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) { + size_t count = read_fd.get_stat().st_size; + do { + ssize_t res; + if ((res = ::sendfile(write_fd.fd, read_fd.fd, nullptr, count)) == -1) { + ec = capture_errno(); + return false; + } + count -= res; + } while (count > 0); - return true; -} -#elif defined(_LIBCPP_USE_COPYFILE) -bool copy_file_impl_copyfile(FileDescriptor& read_fd, FileDescriptor& write_fd, - error_code& ec) { - struct CopyFileState { - copyfile_state_t state; - CopyFileState() { state = copyfile_state_alloc(); } - ~CopyFileState() { copyfile_state_free(state); } - - private: - CopyFileState(CopyFileState const&) = delete; - CopyFileState& operator=(CopyFileState const&) = delete; - }; + ec.clear(); - CopyFileState cfs; - if (fcopyfile(read_fd.fd, write_fd.fd, cfs.state, COPYFILE_DATA) < 0) { - ec = capture_errno(); - return false; + return true; } +#elif defined(_LIBCPP_FILESYSTEM_USE_COPYFILE) + bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) { + struct CopyFileState { + copyfile_state_t state; + CopyFileState() { state = copyfile_state_alloc(); } + ~CopyFileState() { copyfile_state_free(state); } - ec.clear(); - return true; -} -#endif + private: + CopyFileState(CopyFileState const&) = delete; + CopyFileState& operator=(CopyFileState const&) = delete; + }; -// Note: This function isn't guarded by ifdef's even though it may be unused -// in order to assure it still compiles. -__attribute__((unused)) bool copy_file_impl_default(FileDescriptor& read_fd, - FileDescriptor& write_fd, - error_code& ec) { - ifstream in; - in.__open(read_fd.fd, ios::binary); - if (!in.is_open()) { - // This assumes that __open didn't reset the error code. - ec = capture_errno(); - return false; - } - ofstream out; - out.__open(write_fd.fd, ios::binary); - if (!out.is_open()) { - ec = capture_errno(); - return false; - } + CopyFileState cfs; + if (fcopyfile(read_fd.fd, write_fd.fd, cfs.state, COPYFILE_DATA) < 0) { + ec = capture_errno(); + return false; + } - if (in.good() && out.good()) { - using InIt = istreambuf_iterator<char>; - using OutIt = ostreambuf_iterator<char>; - InIt bin(in); - InIt ein; - OutIt bout(out); - copy(bin, ein, bout); - } - if (out.fail() || in.fail()) { - ec = make_error_code(errc::io_error); - return false; + ec.clear(); + return true; } +#elif defined(_LIBCPP_FILESYSTEM_USE_FSTREAM) + bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) { + ifstream in; + in.__open(read_fd.fd, ios::binary); + if (!in.is_open()) { + // This assumes that __open didn't reset the error code. + ec = capture_errno(); + return false; + } + read_fd.fd = -1; + ofstream out; + out.__open(write_fd.fd, ios::binary); + if (!out.is_open()) { + ec = capture_errno(); + return false; + } + write_fd.fd = -1; + + if (in.good() && out.good()) { + using InIt = istreambuf_iterator<char>; + using OutIt = ostreambuf_iterator<char>; + InIt bin(in); + InIt ein; + OutIt bout(out); + copy(bin, ein, bout); + } + if (out.fail() || in.fail()) { + ec = make_error_code(errc::io_error); + return false; + } - ec.clear(); - return true; -} - -bool copy_file_impl(FileDescriptor& from, FileDescriptor& to, error_code& ec) { -#if defined(_LIBCPP_USE_SENDFILE) - return copy_file_impl_sendfile(from, to, ec); -#elif defined(_LIBCPP_USE_COPYFILE) - return copy_file_impl_copyfile(from, to, ec); + ec.clear(); + return true; + } #else - return copy_file_impl_default(from, to, ec); -#endif -} +# error "Unknown implementation for copy_file_impl" +#endif // copy_file_impl implementation -} // namespace -} // namespace detail +} // end anonymous namespace +} // end namespace detail bool __copy_file(const path& from, const path& to, copy_options options, error_code* ec) { @@ -870,8 +946,17 @@ bool __create_directory(const path& p, error_code* ec) { if (::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0) return true; - if (errno != EEXIST) + + if (errno == EEXIST) { + error_code mec = capture_errno(); + error_code ignored_ec; + const file_status st = status(p, ignored_ec); + if (!is_directory(st)) { + err.report(mec); + } + } else { err.report(capture_errno()); + } return false; } @@ -889,8 +974,17 @@ bool __create_directory(path const& p, path const& attributes, error_code* ec) { if (::mkdir(p.c_str(), attr_stat.st_mode) == 0) return true; - if (errno != EEXIST) + + if (errno == EEXIST) { + error_code mec = capture_errno(); + error_code ignored_ec; + const file_status st = status(p, ignored_ec); + if (!is_directory(st)) { + err.report(mec); + } + } else { err.report(capture_errno()); + } return false; } @@ -1225,10 +1319,10 @@ path __temp_directory_path(error_code* ec) { error_code m_ec; file_status st = detail::posix_stat(p, &m_ec); if (!status_known(st)) - return err.report(m_ec, "cannot access path \"%s\"", p); + return err.report(m_ec, "cannot access path \"" PS_FMT "\"", p); if (!exists(st) || !is_directory(st)) - return err.report(errc::not_a_directory, "path \"%s\" is not a directory", + return err.report(errc::not_a_directory, "path \"" PS_FMT "\" is not a directory", p); return p; @@ -1284,7 +1378,7 @@ path& path::replace_extension(path const& replacement) { } if (!replacement.empty()) { if (replacement.native()[0] != '.') { - __pn_ += "."; + __pn_ += PS("."); } __pn_.append(replacement.__pn_); } @@ -1314,7 +1408,7 @@ string_view_t path::__root_path_raw() const { auto PP = PathParser::CreateBegin(__pn_); if (PP.State == PathParser::PS_InRootName) { auto NextCh = PP.peek(); - if (NextCh && *NextCh == '/') { + if (NextCh && isSeparator(*NextCh)) { ++PP; return createView(__pn_.data(), &PP.RawEntry.back()); } @@ -1406,12 +1500,16 @@ enum PathPartKind : unsigned char { static PathPartKind ClassifyPathPart(string_view_t Part) { if (Part.empty()) return PK_TrailingSep; - if (Part == ".") + if (Part == PS(".")) return PK_Dot; - if (Part == "..") + if (Part == PS("..")) return PK_DotDot; - if (Part == "/") + if (Part == PS("/")) + return PK_RootSep; +#if defined(_LIBCPP_WIN32API) + if (Part == PS("\\")) return PK_RootSep; +#endif return PK_Filename; } @@ -1459,7 +1557,7 @@ path path::lexically_normal() const { NewPathSize -= Parts.back().first.size(); Parts.pop_back(); } else if (LastKind != PK_RootSep) - AddPart(PK_DotDot, ".."); + AddPart(PK_DotDot, PS("..")); MaybeNeedTrailingSep = LastKind == PK_Filename; break; } @@ -1474,7 +1572,7 @@ path path::lexically_normal() const { } // [fs.path.generic]p6.8: If the path is empty, add a dot. if (Parts.empty()) - return "."; + return PS("."); // [fs.path.generic]p6.7: If the last filename is dot-dot, remove any // trailing directory-separator. @@ -1486,7 +1584,7 @@ path path::lexically_normal() const { Result /= PK.first; if (NeedTrailingSep) - Result /= ""; + Result /= PS(""); return Result; } @@ -1495,9 +1593,9 @@ static int DetermineLexicalElementCount(PathParser PP) { int Count = 0; for (; PP; ++PP) { auto Elem = *PP; - if (Elem == "..") + if (Elem == PS("..")) --Count; - else if (Elem != "." && Elem != "") + else if (Elem != PS(".") && Elem != PS("")) ++Count; } return Count; @@ -1544,15 +1642,15 @@ path path::lexically_relative(const path& base) const { return {}; // if n == 0 and (a == end() || a->empty()), returns path("."); otherwise - if (ElemCount == 0 && (PP.atEnd() || *PP == "")) - return "."; + if (ElemCount == 0 && (PP.atEnd() || *PP == PS(""))) + return PS("."); // return a path constructed with 'n' dot-dot elements, followed by the the // elements of '*this' after the mismatch. path Result; // FIXME: Reserve enough room in Result that it won't have to re-allocate. while (ElemCount--) - Result /= ".."; + Result /= PS(".."); for (; PP; ++PP) Result /= *PP; return Result; @@ -1565,7 +1663,7 @@ static int CompareRootName(PathParser *LHS, PathParser *RHS) { return 0; auto GetRootName = [](PathParser *Parser) -> string_view_t { - return Parser->inRootName() ? **Parser : ""; + return Parser->inRootName() ? **Parser : PS(""); }; int res = GetRootName(LHS).compare(GetRootName(RHS)); ConsumeRootName(LHS); @@ -1674,6 +1772,36 @@ path::iterator& path::iterator::__decrement() { return *this; } +#if defined(_LIBCPP_WIN32API) +//////////////////////////////////////////////////////////////////////////// +// Windows path conversions +size_t __wide_to_char(const wstring &str, char *out, size_t outlen) { + if (str.empty()) + return 0; + ErrorHandler<size_t> err("__wide_to_char", nullptr); + UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; + BOOL used_default = FALSE; + int ret = WideCharToMultiByte(codepage, 0, str.data(), str.size(), out, + outlen, nullptr, &used_default); + if (ret <= 0 || used_default) + return err.report(errc::illegal_byte_sequence); + return ret; +} + +size_t __char_to_wide(const string &str, wchar_t *out, size_t outlen) { + if (str.empty()) + return 0; + ErrorHandler<size_t> err("__char_to_wide", nullptr); + UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; + int ret = MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, str.data(), + str.size(), out, outlen); + if (ret <= 0) + return err.report(errc::illegal_byte_sequence); + return ret; +} +#endif + + /////////////////////////////////////////////////////////////////////////////// // directory entry definitions /////////////////////////////////////////////////////////////////////////////// diff --git a/contrib/llvm-project/libcxx/src/include/config_elast.h b/contrib/llvm-project/libcxx/src/include/config_elast.h index 501cbc4ffeba..3113f9fb5cd1 100644 --- a/contrib/llvm-project/libcxx/src/include/config_elast.h +++ b/contrib/llvm-project/libcxx/src/include/config_elast.h @@ -17,10 +17,14 @@ #include <errno.h> #endif +// Note: _LIBCPP_ELAST needs to be defined only on platforms +// where strerror/strerror_r can't handle out-of-range errno values. #if defined(ELAST) #define _LIBCPP_ELAST ELAST #elif defined(_NEWLIB_VERSION) #define _LIBCPP_ELAST __ELASTERROR +#elif defined(__NuttX__) +// No _LIBCPP_ELAST needed on NuttX #elif defined(__Fuchsia__) // No _LIBCPP_ELAST needed on Fuchsia #elif defined(__wasi__) diff --git a/contrib/llvm-project/libcxx/src/include/refstring.h b/contrib/llvm-project/libcxx/src/include/refstring.h index e464b79ba89c..cefd7caf0f20 100644 --- a/contrib/llvm-project/libcxx/src/include/refstring.h +++ b/contrib/llvm-project/libcxx/src/include/refstring.h @@ -13,12 +13,25 @@ #include <stdexcept> #include <cstddef> #include <cstring> -#ifdef __APPLE__ -#include <dlfcn.h> -#include <mach-o/dyld.h> -#endif #include "atomic_support.h" +// MacOS and iOS used to ship with libstdc++, and still support old applications +// linking against libstdc++. The libc++ and libstdc++ exceptions are supposed +// to be ABI compatible, such that they can be thrown from one library and caught +// in the other. +// +// For that reason, we must look for libstdc++ in the same process and if found, +// check the string stored in the exception object to see if it is the GCC empty +// string singleton before manipulating the reference count. This is done so that +// if an exception is created with a zero-length string in libstdc++, libc++abi +// won't try to delete the memory. +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || \ + defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) +# define _LIBCPP_CHECK_FOR_GCC_EMPTY_STRING_STORAGE +# include <dlfcn.h> +# include <mach-o/dyld.h> +#endif + _LIBCPP_BEGIN_NAMESPACE_STD namespace __refstring_imp { namespace { @@ -40,7 +53,7 @@ inline char * data_from_rep(_Rep_base *rep) noexcept { return data + sizeof(*rep); } -#if defined(__APPLE__) +#if defined(_LIBCPP_CHECK_FOR_GCC_EMPTY_STRING_STORAGE) inline const char* compute_gcc_empty_string_storage() _NOEXCEPT { @@ -115,7 +128,7 @@ __libcpp_refstring::~__libcpp_refstring() { inline bool __libcpp_refstring::__uses_refcount() const { -#ifdef __APPLE__ +#if defined(_LIBCPP_CHECK_FOR_GCC_EMPTY_STRING_STORAGE) return __imp_ != get_gcc_empty_string_storage(); #else return true; diff --git a/contrib/llvm-project/libcxx/src/ios.cpp b/contrib/llvm-project/libcxx/src/ios.cpp index 2dc84be82873..3a9296465777 100644 --- a/contrib/llvm-project/libcxx/src/ios.cpp +++ b/contrib/llvm-project/libcxx/src/ios.cpp @@ -15,30 +15,14 @@ #include "__locale" #include "algorithm" #include "include/config_elast.h" -#include "istream" #include "limits" #include "memory" #include "new" -#include "streambuf" #include "string" #include "__undef_macros" _LIBCPP_BEGIN_NAMESPACE_STD -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ios<char>; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ios<wchar_t>; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_streambuf<char>; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_streambuf<wchar_t>; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istream<char>; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istream<wchar_t>; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostream<char>; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostream<wchar_t>; - -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_iostream<char>; - class _LIBCPP_HIDDEN __iostream_category : public __do_message { diff --git a/contrib/llvm-project/libcxx/src/ios.instantiations.cpp b/contrib/llvm-project/libcxx/src/ios.instantiations.cpp new file mode 100644 index 000000000000..1a23687d128d --- /dev/null +++ b/contrib/llvm-project/libcxx/src/ios.instantiations.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "__config" +#include "fstream" +#include "ios" +#include "istream" +#include "ostream" +#include "sstream" +#include "streambuf" + + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Original explicit instantiations provided in the library +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ios<char>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ios<wchar_t>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_streambuf<char>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_streambuf<wchar_t>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istream<char>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istream<wchar_t>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostream<char>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostream<wchar_t>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_iostream<char>; + +// Additional instantiations added later. Whether programs rely on these being +// available is protected by _LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1. +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringbuf<char>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringstream<char>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostringstream<char>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istringstream<char>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ifstream<char>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ofstream<char>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_filebuf<char>; + +// Add more here if needed... + +_LIBCPP_END_NAMESPACE_STD diff --git a/contrib/llvm-project/libcxx/src/iostream.cpp b/contrib/llvm-project/libcxx/src/iostream.cpp index ad1920abc657..ea95534c7667 100644 --- a/contrib/llvm-project/libcxx/src/iostream.cpp +++ b/contrib/llvm-project/libcxx/src/iostream.cpp @@ -77,7 +77,7 @@ __asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_t #endif ; -_LIBCPP_HIDDEN ios_base::Init __start_std_streams; +_LIBCPP_HIDDEN ios_base::Init __start_std_streams _LIBCPP_INIT_PRIORITY_MAX; // On Windows the TLS storage for locales needs to be initialized before we create // the standard streams, otherwise it may not be alive during program termination diff --git a/contrib/llvm-project/libcxx/src/locale.cpp b/contrib/llvm-project/libcxx/src/locale.cpp index b9180880e494..a0209d0ce8cf 100644 --- a/contrib/llvm-project/libcxx/src/locale.cpp +++ b/contrib/llvm-project/libcxx/src/locale.cpp @@ -29,8 +29,8 @@ #include "cwctype" #include "__sso_allocator" #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) -#include "support/win32/locale_win32.h" -#elif !defined(__BIONIC__) +#include "__support/win32/locale_win32.h" +#elif !defined(__BIONIC__) && !defined(__NuttX__) #include <langinfo.h> #endif #include <stdlib.h> @@ -158,7 +158,7 @@ const locale::category locale::all; class _LIBCPP_HIDDEN locale::__imp : public facet { - enum {N = 28}; + enum {N = 30}; #if defined(_LIBCPP_COMPILER_MSVC) // FIXME: MSVC doesn't support aligned parameters by value. // I can't get the __sso_allocator to work here @@ -202,8 +202,14 @@ locale::__imp::__imp(size_t refs) install(&make<_VSTD::ctype<wchar_t> >(1u)); install(&make<codecvt<char, char, mbstate_t> >(1u)); install(&make<codecvt<wchar_t, char, mbstate_t> >(1u)); +_LIBCPP_SUPPRESS_DEPRECATED_PUSH install(&make<codecvt<char16_t, char, mbstate_t> >(1u)); install(&make<codecvt<char32_t, char, mbstate_t> >(1u)); +_LIBCPP_SUPPRESS_DEPRECATED_POP +#ifndef _LIBCPP_NO_HAS_CHAR8_T + install(&make<codecvt<char16_t, char8_t, mbstate_t> >(1u)); + install(&make<codecvt<char32_t, char8_t, mbstate_t> >(1u)); +#endif install(&make<numpunct<char> >(1u)); install(&make<numpunct<wchar_t> >(1u)); install(&make<num_get<char> >(1u)); @@ -245,8 +251,14 @@ locale::__imp::__imp(const string& name, size_t refs) install(new ctype_byname<wchar_t>(name_)); install(new codecvt_byname<char, char, mbstate_t>(name_)); install(new codecvt_byname<wchar_t, char, mbstate_t>(name_)); +_LIBCPP_SUPPRESS_DEPRECATED_PUSH install(new codecvt_byname<char16_t, char, mbstate_t>(name_)); install(new codecvt_byname<char32_t, char, mbstate_t>(name_)); +_LIBCPP_SUPPRESS_DEPRECATED_POP +#ifndef _LIBCPP_NO_HAS_CHAR8_T + install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name_)); + install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name_)); +#endif install(new numpunct_byname<char>(name_)); install(new numpunct_byname<wchar_t>(name_)); install(new moneypunct_byname<char, false>(name_)); @@ -315,8 +327,14 @@ locale::__imp::__imp(const __imp& other, const string& name, locale::category c) install(new ctype_byname<wchar_t>(name)); install(new codecvt_byname<char, char, mbstate_t>(name)); install(new codecvt_byname<wchar_t, char, mbstate_t>(name)); +_LIBCPP_SUPPRESS_DEPRECATED_PUSH install(new codecvt_byname<char16_t, char, mbstate_t>(name)); install(new codecvt_byname<char32_t, char, mbstate_t>(name)); +_LIBCPP_SUPPRESS_DEPRECATED_POP +#ifndef _LIBCPP_NO_HAS_CHAR8_T + install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name)); + install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name)); +#endif } if (c & locale::monetary) { @@ -385,8 +403,14 @@ locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c) install_from<_VSTD::ctype<char> >(one); install_from<_VSTD::ctype<wchar_t> >(one); install_from<_VSTD::codecvt<char, char, mbstate_t> >(one); +_LIBCPP_SUPPRESS_DEPRECATED_PUSH install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one); install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one); +_LIBCPP_SUPPRESS_DEPRECATED_POP +#ifndef _LIBCPP_NO_HAS_CHAR8_T + install_from<_VSTD::codecvt<char16_t, char8_t, mbstate_t> >(one); + install_from<_VSTD::codecvt<char32_t, char8_t, mbstate_t> >(one); +#endif install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one); } if (c & locale::monetary) @@ -1149,7 +1173,7 @@ ctype<char>::__classic_upper_table() _NOEXCEPT { return _LIBCPP_GET_C_LOCALE->__ctype_toupper; } -#elif __NetBSD__ +#elif defined(__NetBSD__) const short* ctype<char>::__classic_lower_table() _NOEXCEPT { @@ -3171,6 +3195,87 @@ codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT return 4; } +#ifndef _LIBCPP_NO_HAS_CHAR8_T + +// template <> class codecvt<char16_t, char8_t, mbstate_t> + +locale::id codecvt<char16_t, char8_t, mbstate_t>::id; + +codecvt<char16_t, char8_t, mbstate_t>::~codecvt() +{ +} + +codecvt<char16_t, char8_t, mbstate_t>::result +codecvt<char16_t, char8_t, mbstate_t>::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); + const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); + const uint16_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast<uint8_t*>(to); + uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); + uint8_t* _to_nxt = _to; + result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +codecvt<char16_t, char8_t, mbstate_t>::result +codecvt<char16_t, char8_t, mbstate_t>::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); + const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); + const uint8_t* _frm_nxt = _frm; + uint16_t* _to = reinterpret_cast<uint16_t*>(to); + uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); + uint16_t* _to_nxt = _to; + result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +codecvt<char16_t, char8_t, mbstate_t>::result +codecvt<char16_t, char8_t, mbstate_t>::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +codecvt<char16_t, char8_t, mbstate_t>::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +codecvt<char16_t, char8_t, mbstate_t>::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +codecvt<char16_t, char8_t, mbstate_t>::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); + const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); + return utf8_to_utf16_length(_frm, _frm_end, mx); +} + +int +codecvt<char16_t, char8_t, mbstate_t>::do_max_length() const _NOEXCEPT +{ + return 4; +} + +#endif + // template <> class codecvt<char32_t, char, mbstate_t> locale::id codecvt<char32_t, char, mbstate_t>::id; @@ -3248,6 +3353,87 @@ codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT return 4; } +#ifndef _LIBCPP_NO_HAS_CHAR8_T + +// template <> class codecvt<char32_t, char8_t, mbstate_t> + +locale::id codecvt<char32_t, char8_t, mbstate_t>::id; + +codecvt<char32_t, char8_t, mbstate_t>::~codecvt() +{ +} + +codecvt<char32_t, char8_t, mbstate_t>::result +codecvt<char32_t, char8_t, mbstate_t>::do_out(state_type&, + const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, + extern_type* to, extern_type* to_end, extern_type*& to_nxt) const +{ + const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); + const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); + const uint32_t* _frm_nxt = _frm; + uint8_t* _to = reinterpret_cast<uint8_t*>(to); + uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); + uint8_t* _to_nxt = _to; + result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +codecvt<char32_t, char8_t, mbstate_t>::result +codecvt<char32_t, char8_t, mbstate_t>::do_in(state_type&, + const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, + intern_type* to, intern_type* to_end, intern_type*& to_nxt) const +{ + const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); + const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); + const uint8_t* _frm_nxt = _frm; + uint32_t* _to = reinterpret_cast<uint32_t*>(to); + uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); + uint32_t* _to_nxt = _to; + result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); + return r; +} + +codecvt<char32_t, char8_t, mbstate_t>::result +codecvt<char32_t, char8_t, mbstate_t>::do_unshift(state_type&, + extern_type* to, extern_type*, extern_type*& to_nxt) const +{ + to_nxt = to; + return noconv; +} + +int +codecvt<char32_t, char8_t, mbstate_t>::do_encoding() const _NOEXCEPT +{ + return 0; +} + +bool +codecvt<char32_t, char8_t, mbstate_t>::do_always_noconv() const _NOEXCEPT +{ + return false; +} + +int +codecvt<char32_t, char8_t, mbstate_t>::do_length(state_type&, + const extern_type* frm, const extern_type* frm_end, size_t mx) const +{ + const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); + const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); + return utf8_to_ucs4_length(_frm, _frm_end, mx); +} + +int +codecvt<char32_t, char8_t, mbstate_t>::do_max_length() const _NOEXCEPT +{ + return 4; +} + +#endif + // __codecvt_utf8<wchar_t> __codecvt_utf8<wchar_t>::result @@ -5128,7 +5314,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) mb = mbstate_t(); const char* bb = buf; size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); - if (j == size_t(-1)) + if (j == size_t(-1) || j == 0) __throw_runtime_error("locale not supported"); wbe = wbuf + j; __weeks_[i].assign(wbuf, wbe); @@ -5136,7 +5322,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) mb = mbstate_t(); bb = buf; j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); - if (j == size_t(-1)) + if (j == size_t(-1) || j == 0) __throw_runtime_error("locale not supported"); wbe = wbuf + j; __weeks_[i+7].assign(wbuf, wbe); @@ -5149,7 +5335,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) mb = mbstate_t(); const char* bb = buf; size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); - if (j == size_t(-1)) + if (j == size_t(-1) || j == 0) __throw_runtime_error("locale not supported"); wbe = wbuf + j; __months_[i].assign(wbuf, wbe); @@ -5157,7 +5343,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) mb = mbstate_t(); bb = buf; j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); - if (j == size_t(-1)) + if (j == size_t(-1) || j == 0) __throw_runtime_error("locale not supported"); wbe = wbuf + j; __months_[i+12].assign(wbuf, wbe); @@ -6148,7 +6334,11 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t> template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>; template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>; -template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>; +template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>; +template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char8_t, mbstate_t>; +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char8_t, mbstate_t>; +#endif _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/llvm-project/libcxx/src/memory.cpp b/contrib/llvm-project/libcxx/src/memory.cpp index 633c9a6f5658..5a5894fd94e4 100644 --- a/contrib/llvm-project/libcxx/src/memory.cpp +++ b/contrib/llvm-project/libcxx/src/memory.cpp @@ -124,16 +124,12 @@ __shared_weak_count::lock() _NOEXCEPT return nullptr; } -#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC) - const void* __shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT { return nullptr; } -#endif // _LIBCPP_NO_RTTI - #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) _LIBCPP_SAFE_STATIC static const std::size_t __sp_mut_count = 16; diff --git a/contrib/llvm-project/libcxx/src/new.cpp b/contrib/llvm-project/libcxx/src/new.cpp index 901e78565857..9d01330ba7d5 100644 --- a/contrib/llvm-project/libcxx/src/new.cpp +++ b/contrib/llvm-project/libcxx/src/new.cpp @@ -64,7 +64,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC if (size == 0) size = 1; void* p; - while ((p = ::malloc(size)) == 0) + while ((p = ::malloc(size)) == nullptr) { // If malloc fails and there is a new_handler, // call it to try free up memory. @@ -85,7 +85,7 @@ _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) _NOEXCEPT { - void* p = 0; + void* p = nullptr; #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -111,7 +111,7 @@ _LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT { - void* p = 0; + void* p = nullptr; #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -178,15 +178,16 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC size = 1; if (static_cast<size_t>(alignment) < sizeof(void*)) alignment = std::align_val_t(sizeof(void*)); + + // Try allocating memory. If allocation fails and there is a new_handler, + // call it to try free up memory, and try again until it succeeds, or until + // the new_handler decides to terminate. + // + // If allocation fails and there is no new_handler, we throw bad_alloc + // (or return nullptr if exceptions are disabled). void* p; -#if defined(_LIBCPP_MSVCRT_LIKE) - while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr) -#else - while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0) -#endif + while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) { - // If posix_memalign fails and there is a new_handler, - // call it to try free up memory. std::new_handler nh = std::get_new_handler(); if (nh) nh(); @@ -194,7 +195,6 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC #ifndef _LIBCPP_NO_EXCEPTIONS throw std::bad_alloc(); #else - p = nullptr; // posix_memalign doesn't initialize 'p' on failure break; #endif } @@ -206,7 +206,7 @@ _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT { - void* p = 0; + void* p = nullptr; #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -232,7 +232,7 @@ _LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT { - void* p = 0; + void* p = nullptr; #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -251,11 +251,7 @@ _LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t) _NOEXCEPT { -#if defined(_LIBCPP_MSVCRT_LIKE) - ::_aligned_free(ptr); -#else - ::free(ptr); -#endif + std::__libcpp_aligned_free(ptr); } _LIBCPP_WEAK diff --git a/contrib/llvm-project/libcxx/src/optional.cpp b/contrib/llvm-project/libcxx/src/optional.cpp index 3aaf5ea553ef..86d013b3504f 100644 --- a/contrib/llvm-project/libcxx/src/optional.cpp +++ b/contrib/llvm-project/libcxx/src/optional.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "optional" +#include "__availability" namespace std { diff --git a/contrib/llvm-project/libcxx/src/random.cpp b/contrib/llvm-project/libcxx/src/random.cpp index 04adc59f9bc9..29aa43b1e1e1 100644 --- a/contrib/llvm-project/libcxx/src/random.cpp +++ b/contrib/llvm-project/libcxx/src/random.cpp @@ -13,6 +13,7 @@ #define _CRT_RAND_S #endif // defined(_LIBCPP_USING_WIN32_RANDOM) +#include "limits" #include "random" #include "system_error" @@ -29,6 +30,10 @@ #elif defined(_LIBCPP_USING_DEV_RANDOM) #include <fcntl.h> #include <unistd.h> +#if __has_include(<sys/ioctl.h>) && __has_include(<linux/random.h>) +#include <sys/ioctl.h> +#include <linux/random.h> +#endif #elif defined(_LIBCPP_USING_NACL_RANDOM) #include <nacl/nacl_random.h> #endif @@ -172,7 +177,23 @@ random_device::operator()() double random_device::entropy() const _NOEXCEPT { +#if defined(_LIBCPP_USING_DEV_RANDOM) && defined(RNDGETENTCNT) + int ent; + if (::ioctl(__f_, RNDGETENTCNT, &ent) < 0) + return 0; + + if (ent < 0) return 0; + + if (ent > std::numeric_limits<result_type>::digits) + return std::numeric_limits<result_type>::digits; + + return ent; +#elif defined(__OpenBSD__) + return std::numeric_limits<result_type>::digits; +#else + return 0; +#endif } _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/llvm-project/libcxx/src/support/runtime/exception_fallback.ipp b/contrib/llvm-project/libcxx/src/support/runtime/exception_fallback.ipp index 376a0381f545..faa112f7f3a4 100644 --- a/contrib/llvm-project/libcxx/src/support/runtime/exception_fallback.ipp +++ b/contrib/llvm-project/libcxx/src/support/runtime/exception_fallback.ipp @@ -49,7 +49,6 @@ get_terminate() _NOEXCEPT return __libcpp_atomic_load(&__terminate_handler); } -#ifndef __EMSCRIPTEN__ // We provide this in JS _LIBCPP_NORETURN void terminate() _NOEXCEPT @@ -72,9 +71,7 @@ terminate() _NOEXCEPT } #endif // _LIBCPP_NO_EXCEPTIONS } -#endif // !__EMSCRIPTEN__ -#if !defined(__EMSCRIPTEN__) bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; } int uncaught_exceptions() _NOEXCEPT @@ -83,7 +80,6 @@ int uncaught_exceptions() _NOEXCEPT fprintf(stderr, "uncaught_exceptions not yet implemented\n"); ::abort(); } -#endif // !__EMSCRIPTEN__ exception::~exception() _NOEXCEPT diff --git a/contrib/llvm-project/libcxx/src/thread.cpp b/contrib/llvm-project/libcxx/src/thread.cpp index 5f44e9e40fc7..5959d8b71103 100644 --- a/contrib/llvm-project/libcxx/src/thread.cpp +++ b/contrib/llvm-project/libcxx/src/thread.cpp @@ -14,17 +14,9 @@ #include "vector" #include "future" #include "limits" -#include <sys/types.h> - -#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) -# include <sys/param.h> -# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__) -# include <sys/sysctl.h> -# endif -#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) #if __has_include(<unistd.h>) -#include <unistd.h> +# include <unistd.h> // for sysconf #endif #if defined(__NetBSD__) @@ -80,13 +72,7 @@ thread::detach() unsigned thread::hardware_concurrency() _NOEXCEPT { -#if defined(CTL_HW) && defined(HW_NCPU) - unsigned n; - int mib[2] = {CTL_HW, HW_NCPU}; - std::size_t s = sizeof(n); - sysctl(mib, 2, &n, &s, 0, 0); - return n; -#elif defined(_SC_NPROCESSORS_ONLN) +#if defined(_SC_NPROCESSORS_ONLN) long result = sysconf(_SC_NPROCESSORS_ONLN); // sysconf returns -1 if the name is invalid, the option does not exist or // does not have a definite limit. |