[libcxx-commits] [libcxx] 2d34cb7 - [libc++] Implement `thread::id` comparators as free functions
Adrian Vogelsgesang via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Aug 10 11:41:02 PDT 2022
Author: Adrian Vogelsgesang
Date: 2022-08-10T11:39:50-07:00
New Revision: 2d34cb74b5257ecddfb5781c413232f4ecf99016
URL: https://github.com/llvm/llvm-project/commit/2d34cb74b5257ecddfb5781c413232f4ecf99016
DIFF: https://github.com/llvm/llvm-project/commit/2d34cb74b5257ecddfb5781c413232f4ecf99016.diff
LOG: [libc++] Implement `thread::id` comparators as free functions
So far, the `thread::id` comparators were implemented as hidden friends.
This was non-conforming and lead to incorrectly rejected C++ code, as
can be seen in the linked Github issue.
Fixes https://github.com/llvm/llvm-project/issues/56187
Differential Revision: https://reviews.llvm.org/D131430
Added:
Modified:
libcxx/docs/ReleaseNotes.rst
libcxx/include/__threading_support
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp
libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index e8f1f9d0068d4..9eed86811406a 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -48,6 +48,12 @@ Deprecations and Removals
Upcoming Deprecations and Removals
----------------------------------
+API Changes
+-----------
+- The comparison operators on ``thread::id`` are now defined as free-standing
+ functions instead of as hidden friends, in conformance with the C++ standard.
+ Also see `issue 56187 <https://github.com/llvm/llvm-project/issues/56187>`_.
+
ABI Affecting Changes
---------------------
diff --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support
index a7f0da972a8d0..c9119f3b2dffc 100644
--- a/libcxx/include/__threading_support
+++ b/libcxx/include/__threading_support
@@ -613,36 +613,12 @@ public:
_LIBCPP_INLINE_VISIBILITY
__thread_id() _NOEXCEPT : __id_(0) {}
- friend _LIBCPP_INLINE_VISIBILITY
- bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT
- { // don't pass id==0 to underlying routines
- if (__x.__id_ == 0) return __y.__id_ == 0;
- if (__y.__id_ == 0) return false;
- return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
- }
- friend _LIBCPP_INLINE_VISIBILITY
- bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT
- {return !(__x == __y);}
- friend _LIBCPP_INLINE_VISIBILITY
- bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT
- { // id==0 is always less than any other thread_id
- if (__x.__id_ == 0) return __y.__id_ != 0;
- if (__y.__id_ == 0) return false;
- return __libcpp_thread_id_less(__x.__id_, __y.__id_);
- }
- friend _LIBCPP_INLINE_VISIBILITY
- bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT
- {return !(__y < __x);}
- friend _LIBCPP_INLINE_VISIBILITY
- bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT
- {return __y < __x ;}
- friend _LIBCPP_INLINE_VISIBILITY
- bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT
- {return !(__x < __y);}
-
_LIBCPP_INLINE_VISIBILITY
void __reset() { __id_ = 0; }
+ friend _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT;
+ friend _LIBCPP_HIDE_FROM_ABI bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT;
+
template<class _CharT, class _Traits>
friend
_LIBCPP_INLINE_VISIBILITY
@@ -658,6 +634,35 @@ private:
friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
};
+inline _LIBCPP_HIDE_FROM_ABI
+bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT {
+ // Don't pass id==0 to underlying routines
+ if (__x.__id_ == 0)
+ return __y.__id_ == 0;
+ if (__y.__id_ == 0)
+ return false;
+ return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT {
+ return !(__x == __y);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI
+bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT {
+ // id==0 is always less than any other thread_id
+ if (__x.__id_ == 0)
+ return __y.__id_ != 0;
+ if (__y.__id_ == 0)
+ return false;
+ return __libcpp_thread_id_less(__x.__id_, __y.__id_);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); }
+inline _LIBCPP_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; }
+inline _LIBCPP_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); }
+
namespace this_thread
{
diff --git a/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp b/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp
index 8d083e29451b8..01d505c325cc7 100644
--- a/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp
+++ b/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp
@@ -31,5 +31,11 @@ int main(int, char**)
assert(!(id1 == id0));
assert( (id1 != id0));
- return 0;
+ // Regression tests for https://github.com/llvm/llvm-project/issues/56187
+ // libc++ previously declared the comparison operators as hidden friends
+ // which was non-conforming.
+ assert(!std::operator==(id1, id0));
+ assert(std::operator!=(id1, id0));
+
+ return 0;
}
diff --git a/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp b/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp
index e1438da1d19d7..7519f04ebb353 100644
--- a/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp
+++ b/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp
@@ -42,5 +42,13 @@ int main(int, char**)
assert( (id0 >= id2));
}
- return 0;
+ // Regression tests for https://github.com/llvm/llvm-project/issues/56187
+ // libc++ previously declared the comparison operators as hidden friends
+ // which was non-conforming.
+ assert(!std::operator<(id0, id1));
+ assert(std::operator<=(id0, id1));
+ assert(!std::operator>(id0, id1));
+ assert(std::operator>=(id0, id1));
+
+ return 0;
}
More information about the libcxx-commits
mailing list