blob: edabebf0fbd54b61ba5f87b1fb2c0dd36a724436 [file] [log] [blame]
From 5234a25254d53034f8706ac172f32fffdd237a69 Mon Sep 17 00:00:00 2001
From: Chih-Hung Hsieh <chh@google.com>
Date: Mon, 22 Feb 2021 15:57:50 -0800
Subject: [PATCH] Revert babd3aefc91 and 6 changes after it.
* Revert "[libcxx] Avoid overflows in the windows __libcpp_steady_clock_now()"
This reverts commit 02f1d28ed6b8f33445dae3beed8b6cc8dada4312.
* Revert "[libc++] NFCI: Refactor chrono.cpp to make it easier to support new platforms"
This reverts commit 2dec36e5326eae08507464bbe19bf1004898293a.
* Revert "[libc++] Check _LIBCPP_USE_CLOCK_GETTIME before using clock_gettime"
This reverts commit f78bb4d84eee55c5d3bb1f3322c1e346e3388572.
* Revert "[libcxx] Avoid double frees of file descriptors in the fallback ifstream/ofstream codepath"
This reverts commit 08b4cc5e0d2625e85ed4af9aad17ccc0876e3bd3.
* Revert "[libc++] Fix a few warnings"
This reverts commit acd7be74ca12f8f08e52d6d80850a9b230109134.
* Revert "[libc++][filesystem] Only include <fstream> when we actually need it in copy_file_impl"
This reverts commit 17dcf85ebe4cfbd3f811848f6d9ebc486b3387e9.
* Revert "[libc++] Remove workarounds for the lack of clock_gettime on older macOS platforms"
This reverts commit babd3aefc9193b44ad0620a2cfd63ebb6ad7e952.
---
libcxx/docs/index.rst | 35 +---
libcxx/src/chrono.cpp | 188 +++++++++++-------
libcxx/src/filesystem/operations.cpp | 186 +++++++++--------
libcxx/src/include/apple_availability.h | 18 ++
libcxx/src/locale.cpp | 2 +-
.../time.clock/time.clock.steady/now.pass.cpp | 2 -
6 files changed, 250 insertions(+), 181 deletions(-)
diff --git a/libcxx/docs/index.rst b/libcxx/docs/index.rst
index ecece32228d9..7fee601fdf67 100644
--- a/libcxx/docs/index.rst
+++ b/libcxx/docs/index.rst
@@ -92,46 +92,25 @@ reasons, but some of the major ones are:
Platform and Compiler Support
-----------------------------
-For using the libc++ headers
-############################
-The libc++ headers are known to work on the following platforms, using GCC and
-Clang. Note that functionality provided by ``<atomic>`` is only functional with
-Clang and GCC.
-
-============ ==================== ============
-OS Arch Compilers
-============ ==================== ============
-macOS 10.9+ i386, x86_64 Clang, GCC
-FreeBSD 10+ i386, x86_64, ARM Clang, GCC
-Linux i386, x86_64 Clang, GCC
-============ ==================== ============
-
-The following minimum compiler versions are required:
-
-* Clang 4.0 and above
-* GCC 5.0 and above.
-
-The C++03 dialect is only supported with Clang.
-
-For building the libc++ library
-###############################
-Building the libc++ library (static or shared) requires some features from
-the operating system. As such, it has its own set of (slightly different)
-system requirements.
+libc++ is known to work on the following platforms, using gcc and
+clang.
+Note that functionality provided by ``<atomic>`` is only functional with clang
+and GCC.
============ ==================== ============ ========================
OS Arch Compilers ABI Library
============ ==================== ============ ========================
-macOS 10.12+ i386, x86_64 Clang, GCC libc++abi
+macOS i386, x86_64 Clang, GCC libc++abi
FreeBSD 10+ i386, x86_64, ARM Clang, GCC libcxxrt, libc++abi
Linux i386, x86_64 Clang, GCC libc++abi
============ ==================== ============ ========================
-The following minimum compiler versions are required:
+The following minimum compiler versions are strongly recommended.
* Clang 4.0 and above
* GCC 5.0 and above.
+The C++03 dialect is only supported for Clang compilers.
C++ Dialect Support
---------------------
diff --git a/libcxx/src/chrono.cpp b/libcxx/src/chrono.cpp
index 5291d4fa8dc6..a1a456faf2d3 100644
--- a/libcxx/src/chrono.cpp
+++ b/libcxx/src/chrono.cpp
@@ -9,32 +9,40 @@
#include "chrono"
#include "cerrno" // errno
#include "system_error" // __throw_system_error
-#include <time.h> // clock_gettime and CLOCK_{MONOTONIC,REALTIME,MONOTONIC_RAW}
+#include <time.h> // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME
#include "include/apple_availability.h"
#if __has_include(<unistd.h>)
-# include <unistd.h>
-#endif
-
-#if __has_include(<sys/time.h>)
-# include <sys/time.h> // for gettimeofday and timeval
+#include <unistd.h>
#endif
#if !defined(__APPLE__) && _POSIX_TIMERS > 0
-# define _LIBCPP_USE_CLOCK_GETTIME
+#define _LIBCPP_USE_CLOCK_GETTIME
#endif
#if defined(_LIBCPP_WIN32API)
-# define WIN32_LEAN_AND_MEAN
-# define VC_EXTRA_LEAN
-# include <windows.h>
-# if _WIN32_WINNT >= _WIN32_WINNT_WIN8
-# include <winapifamily.h>
-# endif
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRA_LEAN
+#include <windows.h>
+#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
+#include <winapifamily.h>
+#endif
+#else
+#if !defined(CLOCK_REALTIME) || !defined(_LIBCPP_USE_CLOCK_GETTIME)
+#include <sys/time.h> // for gettimeofday and timeval
+#endif
#endif // defined(_LIBCPP_WIN32API)
+#if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK)
+#if __APPLE__
+#include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
+#elif !defined(_LIBCPP_WIN32API) && !defined(CLOCK_MONOTONIC)
+#error "Monotonic clock not implemented"
+#endif
+#endif
+
#if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB)
-# pragma comment(lib, "rt")
+#pragma comment(lib, "rt")
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -42,13 +50,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace chrono
{
-//
// system_clock
-//
-#if defined(_LIBCPP_WIN32API)
+const bool system_clock::is_steady;
-static system_clock::time_point __libcpp_system_clock_now() {
+system_clock::time_point
+system_clock::now() _NOEXCEPT
+{
+#if defined(_LIBCPP_WIN32API)
// FILETIME is in 100ns units
using filetime_duration =
_VSTD::chrono::duration<__int64,
@@ -59,42 +68,31 @@ static system_clock::time_point __libcpp_system_clock_now() {
static _LIBCPP_CONSTEXPR const seconds nt_to_unix_epoch{11644473600};
FILETIME ft;
-#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
+#if 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 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() {
+ return time_point(duration_cast<duration>(d - nt_to_unix_epoch));
+#else
+#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
struct timespec tp;
if (0 != clock_gettime(CLOCK_REALTIME, &tp))
__throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
- return system_clock::time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000));
-}
-
+ return 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 system_clock::time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
-}
-
+ return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
+#endif // _LIBCPP_USE_CLOCK_GETTIME && CLOCK_REALTIME
#endif
-
-const bool system_clock::is_steady;
-
-system_clock::time_point
-system_clock::now() _NOEXCEPT
-{
- return __libcpp_system_clock_now();
}
time_t
@@ -109,29 +107,81 @@ 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.
-//
-#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
+const bool steady_clock::is_steady;
#if defined(__APPLE__)
-// 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.
-static steady_clock::time_point __libcpp_steady_clock_now() {
+// Darwin libc versions >= 1133 provide ns precision via CLOCK_MONOTONIC_RAW
+#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC_RAW)
+steady_clock::time_point
+steady_clock::now() _NOEXCEPT
+{
struct timespec tp;
if (0 != clock_gettime(CLOCK_MONOTONIC_RAW, &tp))
__throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC_RAW) failed");
- return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
+ return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
+}
+
+#else
+// 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;
+}
+
+steady_clock::time_point
+steady_clock::now() _NOEXCEPT
+{
+ static FP fp = init_steady_clock();
+ return time_point(duration(fp()));
}
+#endif // defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC_RAW)
#elif defined(_LIBCPP_WIN32API)
@@ -143,43 +193,43 @@ static steady_clock::time_point __libcpp_steady_clock_now() {
static LARGE_INTEGER
__QueryPerformanceFrequency()
{
- LARGE_INTEGER val;
- (void) QueryPerformanceFrequency(&val);
- return val;
+ LARGE_INTEGER val;
+ (void) QueryPerformanceFrequency(&val);
+ return val;
}
-static steady_clock::time_point __libcpp_steady_clock_now() {
+steady_clock::time_point
+steady_clock::now() _NOEXCEPT
+{
static const LARGE_INTEGER freq = __QueryPerformanceFrequency();
LARGE_INTEGER counter;
(void) QueryPerformanceCounter(&counter);
- 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));
+ return time_point(duration(counter.QuadPart * nano::den / freq.QuadPart));
}
#elif defined(CLOCK_MONOTONIC)
-static steady_clock::time_point __libcpp_steady_clock_now() {
+// On Apple platforms only CLOCK_UPTIME_RAW, CLOCK_MONOTONIC_RAW or
+// mach_absolute_time are able to time functions in the nanosecond range.
+// Thus, they are the only acceptable implementations of steady_clock.
+#ifdef __APPLE__
+#error "Never use CLOCK_MONOTONIC for steady_clock::now on Apple platforms"
+#endif
+
+steady_clock::time_point
+steady_clock::now() _NOEXCEPT
+{
struct timespec tp;
if (0 != clock_gettime(CLOCK_MONOTONIC, &tp))
__throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed");
- return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
+ return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
}
#else
-# error "Monotonic clock not implemented on this platform"
+#error "Monotonic clock not implemented"
#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/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp
index 7db2d1ff0074..12cf5b399e90 100644
--- a/libcxx/src/filesystem/operations.cpp
+++ b/libcxx/src/filesystem/operations.cpp
@@ -9,6 +9,7 @@
#include "filesystem"
#include "array"
#include "iterator"
+#include "fstream"
#include "string_view"
#include "type_traits"
#include "vector"
@@ -29,23 +30,33 @@
#include <time.h>
#include <fcntl.h> /* values for fchmodat */
-#if __has_include(<sys/sendfile.h>)
-# include <sys/sendfile.h>
-# define _LIBCPP_FILESYSTEM_USE_SENDFILE
+#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
#elif defined(__APPLE__) || __has_include(<copyfile.h>)
-# include <copyfile.h>
-# define _LIBCPP_FILESYSTEM_USE_COPYFILE
-#else
-# include "fstream"
-# define _LIBCPP_FILESYSTEM_USE_FSTREAM
+#include <copyfile.h>
+#define _LIBCPP_USE_COPYFILE
#endif
-#if !defined(CLOCK_REALTIME)
-# include <sys/time.h> // for gettimeofday and timeval
+#if !defined(__APPLE__) && _POSIX_TIMERS > 0
+#define _LIBCPP_USE_CLOCK_GETTIME
#endif
+#if !defined(CLOCK_REALTIME) || !defined(_LIBCPP_USE_CLOCK_GETTIME)
+#include <sys/time.h> // for gettimeofday and timeval
+#endif // !defined(CLOCK_REALTIME)
+
#if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB)
-# pragma comment(lib, "rt")
+#pragma comment(lib, "rt")
+#endif
+
+#if defined(_LIBCPP_COMPILER_GCC)
+#if _GNUC_VER < 500
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
#endif
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
@@ -565,7 +576,7 @@ const bool _FilesystemClock::is_steady;
_FilesystemClock::time_point _FilesystemClock::now() noexcept {
typedef chrono::duration<rep> __secs;
-#if defined(CLOCK_REALTIME)
+#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
typedef chrono::duration<rep, nano> __nsecs;
struct timespec tp;
if (0 != clock_gettime(CLOCK_REALTIME, &tp))
@@ -577,7 +588,7 @@ _FilesystemClock::time_point _FilesystemClock::now() noexcept {
timeval tv;
gettimeofday(&tv, 0);
return time_point(__secs(tv.tv_sec) + __microsecs(tv.tv_usec));
-#endif // CLOCK_REALTIME
+#endif // _LIBCPP_USE_CLOCK_GETTIME && CLOCK_REALTIME
}
filesystem_error::~filesystem_error() {}
@@ -627,7 +638,7 @@ 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 defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112
+#if _POSIX_VERSION >= 200112
std::unique_ptr<char, decltype(&::free)>
hold(::realpath(p.c_str(), nullptr), &::free);
if (hold.get() == nullptr)
@@ -731,83 +742,96 @@ void __copy(const path& from, const path& to, copy_options options,
namespace detail {
namespace {
-#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);
-
- ec.clear();
-
- 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); }
-
- private:
- CopyFileState(CopyFileState const&) = delete;
- CopyFileState& operator=(CopyFileState const&) = delete;
- };
+#ifdef _LIBCPP_USE_SENDFILE
+bool copy_file_impl_sendfile(FileDescriptor& read_fd, FileDescriptor& write_fd,
+ error_code& ec) {
- CopyFileState cfs;
- if (fcopyfile(read_fd.fd, write_fd.fd, cfs.state, COPYFILE_DATA) < 0) {
+ 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();
- return true;
+ ec.clear();
+
+ 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;
+ };
+
+ CopyFileState cfs;
+ if (fcopyfile(read_fd.fd, write_fd.fd, cfs.state, COPYFILE_DATA) < 0) {
+ ec = capture_errno();
+ return false;
}
-#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;
+ ec.clear();
+ return true;
+}
+#endif
+
+// 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;
+ }
+
+ 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);
#else
-# error "Unknown implementation for copy_file_impl"
-#endif // copy_file_impl implementation
+ return copy_file_impl_default(from, to, ec);
+#endif
+}
-} // end anonymous namespace
-} // end namespace detail
+} // namespace
+} // namespace detail
bool __copy_file(const path& from, const path& to, copy_options options,
error_code* ec) {
diff --git a/libcxx/src/include/apple_availability.h b/libcxx/src/include/apple_availability.h
index 0f999d3feafb..f0a5800e8f3a 100644
--- a/libcxx/src/include/apple_availability.h
+++ b/libcxx/src/include/apple_availability.h
@@ -28,6 +28,24 @@
#endif
#endif // __ENVIRONMENT_.*_VERSION_MIN_REQUIRED__
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101200
+#define _LIBCPP_USE_CLOCK_GETTIME
+#endif
+#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
+#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 100000
+#define _LIBCPP_USE_CLOCK_GETTIME
+#endif
+#elif defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__)
+#if __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 100000
+#define _LIBCPP_USE_CLOCK_GETTIME
+#endif
+#elif defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__)
+#if __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 30000
+#define _LIBCPP_USE_CLOCK_GETTIME
+#endif
+#endif // __ENVIRONMENT_.*_VERSION_MIN_REQUIRED__
+
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500
#define _LIBCPP_USE_ULOCK
diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp
index f109389f68f3..1bab117ca5c2 100644
--- a/libcxx/src/locale.cpp
+++ b/libcxx/src/locale.cpp
@@ -1173,7 +1173,7 @@ ctype<char>::__classic_upper_table() _NOEXCEPT
{
return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
}
-#elif defined(__NetBSD__)
+#elif __NetBSD__
const short*
ctype<char>::__classic_lower_table() _NOEXCEPT
{
diff --git a/libcxx/test/std/utilities/time/time.clock/time.clock.steady/now.pass.cpp b/libcxx/test/std/utilities/time/time.clock/time.clock.steady/now.pass.cpp
index 14dc9a9832dc..4b8104dd1a6f 100644
--- a/libcxx/test/std/utilities/time/time.clock/time.clock.steady/now.pass.cpp
+++ b/libcxx/test/std/utilities/time/time.clock/time.clock.steady/now.pass.cpp
@@ -25,8 +25,6 @@ int main(int, char**)
C::time_point t1 = C::now();
C::time_point t2 = C::now();
assert(t2 >= t1);
- // make sure t2 didn't wrap around
- assert(t2 > std::chrono::time_point<C>());
return 0;
}
--
2.30.0.617.g56c4b15f3c-goog