[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