[libcxx-commits] [libcxx] 40950a4 - [libc++] ADL-proof <thread>, and eliminate `using namespace chrono`.

Arthur O'Dwyer via libcxx-commits libcxx-commits at lists.llvm.org
Tue Dec 1 19:14:13 PST 2020


Author: Arthur O'Dwyer
Date: 2020-12-01T22:13:39-05:00
New Revision: 40950a44b9a6aefe17b130e291f8728b34844bce

URL: https://github.com/llvm/llvm-project/commit/40950a44b9a6aefe17b130e291f8728b34844bce
DIFF: https://github.com/llvm/llvm-project/commit/40950a44b9a6aefe17b130e291f8728b34844bce.diff

LOG: [libc++] ADL-proof <thread>, and eliminate `using namespace chrono`.

Since we know exactly which identifiers we expect to find in `chrono`,
a using-directive seems like massive overkill. Remove the directives
and qualify the names as needed.

One subtle trick here: In two places I replaced `*__p` with `*__p.get()`.
The former is an unqualified call to `operator*` on a class type, which
triggers ADL and breaks the new test. The latter is a call to the
built-in `operator*` on pointers, which specifically
does NOT trigger ADL thanks to [over.match.oper]/1.

Differential Revision: https://reviews.llvm.org/D92243

Added: 
    libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/robust_against_adl.pass.cpp

Modified: 
    libcxx/include/thread

Removed: 
    


################################################################################
diff  --git a/libcxx/include/thread b/libcxx/include/thread
index 6eff1800acdb..34e0c2a23916 100644
--- a/libcxx/include/thread
+++ b/libcxx/include/thread
@@ -277,18 +277,18 @@ inline _LIBCPP_INLINE_VISIBILITY
 void
 __thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>)
 {
-    __invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
+    _VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
 }
 
 template <class _Fp>
 _LIBCPP_INLINE_VISIBILITY
 void* __thread_proxy(void* __vp)
 {
-    // _Fp = std::tuple< unique_ptr<__thread_struct>, Functor, Args...>
-    std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
-    __thread_local_data().set_pointer(_VSTD::get<0>(*__p).release());
+    // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...>
+    unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
+    __thread_local_data().set_pointer(_VSTD::get<0>(*__p.get()).release());
     typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index;
-    __thread_execute(*__p, _Index());
+    _VSTD::__thread_execute(*__p.get(), _Index());
     return nullptr;
 }
 
@@ -300,11 +300,11 @@ thread::thread(_Fp&& __f, _Args&&... __args)
     typedef unique_ptr<__thread_struct> _TSPtr;
     _TSPtr __tsp(new __thread_struct);
     typedef tuple<_TSPtr, typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp;
-    _VSTD::unique_ptr<_Gp> __p(
-            new _Gp(std::move(__tsp),
-                    __decay_copy(_VSTD::forward<_Fp>(__f)),
-                    __decay_copy(_VSTD::forward<_Args>(__args))...));
-    int __ec = __libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
+    unique_ptr<_Gp> __p(
+            new _Gp(_VSTD::move(__tsp),
+                    _VSTD::__decay_copy(_VSTD::forward<_Fp>(__f)),
+                    _VSTD::__decay_copy(_VSTD::forward<_Args>(__args))...));
+    int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
     if (__ec == 0)
         __p.release();
     else
@@ -326,7 +326,7 @@ struct __thread_invoke_pair {
 template <class _Fp>
 void* __thread_proxy_cxx03(void* __vp)
 {
-    std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
+    unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
     __thread_local_data().set_pointer(__p->__tsp_.release());
     (__p->__fn_)();
     return nullptr;
@@ -337,9 +337,9 @@ thread::thread(_Fp __f)
 {
 
     typedef __thread_invoke_pair<_Fp> _InvokePair;
-    typedef std::unique_ptr<_InvokePair> _PairPtr;
+    typedef unique_ptr<_InvokePair> _PairPtr;
     _PairPtr __pp(new _InvokePair(__f));
-    int __ec = __libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
+    int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
     if (__ec == 0)
         __pp.release();
     else
@@ -360,25 +360,24 @@ template <class _Rep, class _Period>
 void
 sleep_for(const chrono::duration<_Rep, _Period>& __d)
 {
-    using namespace chrono;
-    if (__d > duration<_Rep, _Period>::zero())
+    if (__d > chrono::duration<_Rep, _Period>::zero())
     {
 #if defined(_LIBCPP_COMPILER_GCC) && (__powerpc__ || __POWERPC__)
     //  GCC's long double const folding is incomplete for IBM128 long doubles.
-        _LIBCPP_CONSTEXPR duration<long double> _Max = duration<long double>(ULLONG_MAX/1000000000ULL) ;
+        _LIBCPP_CONSTEXPR chrono::duration<long double> _Max = chrono::duration<long double>(ULLONG_MAX/1000000000ULL) ;
 #else
-        _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
+        _LIBCPP_CONSTEXPR chrono::duration<long double> _Max = chrono::nanoseconds::max();
 #endif
-        nanoseconds __ns;
+        chrono::nanoseconds __ns;
         if (__d < _Max)
         {
-            __ns = duration_cast<nanoseconds>(__d);
+            __ns = chrono::duration_cast<chrono::nanoseconds>(__d);
             if (__ns < __d)
                 ++__ns;
         }
         else
-            __ns = nanoseconds::max();
-        sleep_for(__ns);
+            __ns = chrono::nanoseconds::max();
+        this_thread::sleep_for(__ns);
     }
 }
 
@@ -386,7 +385,6 @@ template <class _Clock, class _Duration>
 void
 sleep_until(const chrono::time_point<_Clock, _Duration>& __t)
 {
-    using namespace chrono;
     mutex __mut;
     condition_variable __cv;
     unique_lock<mutex> __lk(__mut);
@@ -399,8 +397,7 @@ inline _LIBCPP_INLINE_VISIBILITY
 void
 sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)
 {
-    using namespace chrono;
-    sleep_for(__t - steady_clock::now());
+    this_thread::sleep_for(__t - chrono::steady_clock::now());
 }
 
 inline _LIBCPP_INLINE_VISIBILITY

diff  --git a/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/robust_against_adl.pass.cpp b/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/robust_against_adl.pass.cpp
new file mode 100644
index 000000000000..400f95263156
--- /dev/null
+++ b/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/robust_against_adl.pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03
+
+// <thread>
+
+// class thread
+
+// template <class F, class ...Args> thread(F&& f, Args&&... args);
+
+#include <thread>
+
+#include "test_macros.h"
+
+struct Incomplete;
+template<class T> struct Holder { T t; };
+
+void f(Holder<Incomplete> *) { }
+
+int main(int, char **)
+{
+    Holder<Incomplete> *p = nullptr;
+    std::thread t(f, p);
+    t.join();
+    return 0;
+}


        


More information about the libcxx-commits mailing list