[libcxx] r272634 - Implement variadic lock_guard.

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 14 18:24:06 PDT 2016


Update on the bot failures:

I've spoken to the owner of the bots and they are planning to upgrade their
Clang versions.
This will get the bots green again.

/Eric

On Mon, Jun 13, 2016 at 11:49 PM, Eric Fiselier <eric at efcs.ca> wrote:

> This is causing some of the libc++ bots to go red.
> `variadic_copy.fail.cpp` is encountering an error, which seems to be a
> clang bug which temporarily existed in 3.9.
> The test passes against current ToT and older clang releases and GCC.
>
> Please do not revert this commit due to that specific failure. I am aware
> of it and I am working to fix it.
>
> On Mon, Jun 13, 2016 at 9:48 PM, Eric Fiselier via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
>
>> Author: ericwf
>> Date: Mon Jun 13 22:48:09 2016
>> New Revision: 272634
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=272634&view=rev
>> Log:
>> Implement variadic lock_guard.
>>
>> Summary:
>> This patch implements the variadic `lock_guard` paper.
>>
>> Making `lock_guard` variadic is a ABI breaking change because the
>> specialization `lock_guard<_Mutex>` mangles differently then when it was
>> the primary template. This change only provides variadic `lock_guard` in
>> ABI V2 or when `_LIBCPP_ABI_VARIADIC_LOCK_GUARD` is defined.
>>
>> Note that in ABI V2 `lock_guard` must always be declared as a variadic
>> template, even in C++03, in order to keep the ABI consistent. For this
>> reason `lock_guard` is forward declared as a variadic template in all
>> standard dialects and therefore depends on variadic templates being
>> provided as an extension in C++03. All supported versions of Clang and GCC
>> provide this extension.
>>
>>
>>
>>
>> Reviewers: mclow.lists
>>
>> Subscribers: K-ballo, mclow.lists, cfe-commits
>>
>> Differential Revision: http://reviews.llvm.org/D21260
>>
>> Added:
>>     libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/
>>
>> libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/
>>
>> libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp
>>
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp
>>
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp
>>
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp
>>
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp
>>
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp
>>
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp
>>
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp
>> Modified:
>>     libcxx/trunk/include/__config
>>     libcxx/trunk/include/__mutex_base
>>     libcxx/trunk/include/mutex
>>
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp
>>     libcxx/trunk/www/cxx1z_status.html
>>
>> Modified: libcxx/trunk/include/__config
>> URL:
>> http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=272634&r1=272633&r2=272634&view=diff
>>
>> ==============================================================================
>> --- libcxx/trunk/include/__config (original)
>> +++ libcxx/trunk/include/__config Mon Jun 13 22:48:09 2016
>> @@ -43,6 +43,7 @@
>>  #define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB
>>  #define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB
>>  #define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
>> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
>>  #endif
>>
>>  #define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y
>>
>> Modified: libcxx/trunk/include/__mutex_base
>> URL:
>> http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__mutex_base?rev=272634&r1=272633&r2=272634&view=diff
>>
>> ==============================================================================
>> --- libcxx/trunk/include/__mutex_base (original)
>> +++ libcxx/trunk/include/__mutex_base Mon Jun 13 22:48:09 2016
>> @@ -76,8 +76,21 @@ constexpr adopt_lock_t  adopt_lock  = ad
>>
>>  #endif
>>
>> +
>> +// Forward declare lock_guard as a variadic template even in C++03 to
>> keep
>> +// the mangling consistent between dialects.
>> +#if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD)
>> +template <class ..._Mutexes>
>> +class _LIBCPP_TYPE_VIS_ONLY lock_guard;
>> +#endif
>> +
>>  template <class _Mutex>
>> -class _LIBCPP_TYPE_VIS_ONLY
>> _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) lock_guard
>> +class _LIBCPP_TYPE_VIS_ONLY
>> _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable)
>> +#if !defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD)
>> +lock_guard
>> +#else
>> +lock_guard<_Mutex>
>> +#endif
>>  {
>>  public:
>>      typedef _Mutex mutex_type;
>> @@ -96,8 +109,8 @@ public:
>>      ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability())
>> {__m_.unlock();}
>>
>>  private:
>> -    lock_guard(lock_guard const&);// = delete;
>> -    lock_guard& operator=(lock_guard const&);// = delete;
>> +    lock_guard(lock_guard const&) _LIBCPP_EQUAL_DELETE;
>> +    lock_guard& operator=(lock_guard const&) _LIBCPP_EQUAL_DELETE;
>>  };
>>
>>  template <class _Mutex>
>>
>> Modified: libcxx/trunk/include/mutex
>> URL:
>> http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/mutex?rev=272634&r1=272633&r2=272634&view=diff
>>
>> ==============================================================================
>> --- libcxx/trunk/include/mutex (original)
>> +++ libcxx/trunk/include/mutex Mon Jun 13 22:48:09 2016
>> @@ -109,6 +109,19 @@ public:
>>      lock_guard& operator=(lock_guard const&) = delete;
>>  };
>>
>> +template <class... MutexTypes> // Variadic lock_guard only provided in
>> ABI V2.
>> +class lock_guard
>> +{
>> +public:
>> +    explicit lock_guard(MutexTypes&... m);
>> +    lock_guard(MutexTypes&... m, adopt_lock_t);
>> +    ~lock_guard();
>> +    lock_guard(lock_guard const&) = delete;
>> +    lock_guard& operator=(lock_guard const&) = delete;
>> +private:
>> +    tuple<MutexTypes&...> pm; // exposition only
>> +};
>> +
>>  template <class Mutex>
>>  class unique_lock
>>  {
>> @@ -427,6 +440,27 @@ lock(_L0& __l0, _L1& __l1, _L2& __l2, _L
>>      __lock_first(0, __l0, __l1, __l2, __l3...);
>>  }
>>
>> +template <class _L0>
>> +inline _LIBCPP_INLINE_VISIBILITY
>> +void __unlock(_L0& __l0) {
>> +    __l0.unlock();
>> +}
>> +
>> +template <class _L0, class _L1>
>> +inline _LIBCPP_INLINE_VISIBILITY
>> +void __unlock(_L0& __l0, _L1& __l1) {
>> +    __l0.unlock();
>> +    __l1.unlock();
>> +}
>> +
>> +template <class _L0, class _L1, class _L2, class ..._L3>
>> +inline _LIBCPP_INLINE_VISIBILITY
>> +void __unlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
>> +    __l0.unlock();
>> +    __l1.unlock();
>> +    _VSTD::__unlock(__l2, __l3...);
>> +}
>> +
>>  #endif  // _LIBCPP_HAS_NO_VARIADICS
>>
>>  #endif // !_LIBCPP_HAS_NO_THREADS
>> @@ -577,6 +611,63 @@ call_once(once_flag& __flag, const _Call
>>
>>  #endif  // _LIBCPP_HAS_NO_VARIADICS
>>
>> +
>> +#if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD) \
>> +    && !defined(_LIBCPP_CXX03_LANG)
>> +template <>
>> +class _LIBCPP_TYPE_VIS_ONLY lock_guard<> {
>> +public:
>> +    explicit lock_guard() = default;
>> +    ~lock_guard() = default;
>> +
>> +    _LIBCPP_INLINE_VISIBILITY
>> +    explicit lock_guard(adopt_lock_t) {}
>> +
>> +    lock_guard(lock_guard const&) = delete;
>> +    lock_guard& operator=(lock_guard const&) = delete;
>> +};
>> +
>> +template <class ..._MArgs>
>> +class _LIBCPP_TYPE_VIS_ONLY lock_guard
>> +{
>> +    static_assert(sizeof...(_MArgs) >= 2, "At least 2 lock types
>> required");
>> +    typedef tuple<_MArgs&...> _MutexTuple;
>> +
>> +public:
>> +    _LIBCPP_INLINE_VISIBILITY
>> +    explicit lock_guard(_MArgs&... __margs)
>> +      : __t_(__margs...)
>> +    {
>> +        _VSTD::lock(__margs...);
>> +    }
>> +
>> +    _LIBCPP_INLINE_VISIBILITY
>> +    lock_guard(_MArgs&... __margs, adopt_lock_t)
>> +        : __t_(__margs...)
>> +    {
>> +    }
>> +
>> +    _LIBCPP_INLINE_VISIBILITY
>> +    ~lock_guard() {
>> +        typedef typename __make_tuple_indices<sizeof...(_MArgs)>::type
>> _Indices;
>> +        __unlock_unpack(_Indices{}, __t_);
>> +    }
>> +
>> +    lock_guard(lock_guard const&) = delete;
>> +    lock_guard& operator=(lock_guard const&) = delete;
>> +
>> +private:
>> +    template <size_t ..._Indx>
>> +    _LIBCPP_INLINE_VISIBILITY
>> +    static void __unlock_unpack(__tuple_indices<_Indx...>, _MutexTuple&
>> __mt) {
>> +        _VSTD::__unlock(_VSTD::get<_Indx>(__mt)...);
>> +    }
>> +
>> +    _MutexTuple __t_;
>> +};
>> +
>> +#endif // _LIBCPP_ABI_VARIADIC_LOCK_GUARD
>> +
>>  _LIBCPP_END_NAMESPACE_STD
>>
>>  #endif  // _LIBCPP_MUTEX
>>
>> Added:
>> libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp?rev=272634&view=auto
>>
>> ==============================================================================
>> ---
>> libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp
>> (added)
>> +++
>> libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp
>> Mon Jun 13 22:48:09 2016
>> @@ -0,0 +1,31 @@
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +//                     The LLVM Compiler Infrastructure
>> +//
>> +// This file is dual licensed under the MIT and the University of
>> Illinois Open
>> +// Source Licenses. See LICENSE.TXT for details.
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +// UNSUPPORTED: libcpp-has-no-threads
>> +
>> +// THIS TESTS C++03 EXTENSIONS.
>> +
>> +// <mutex>
>> +
>> +// template <class ...Mutex> class lock_guard;
>> +
>> +// Test that the the variadic lock guard implementation mangles the same
>> in
>> +// C++11 and C++03. This is important since the mangling of `lock_guard`
>> depends
>> +// on it being declared as a variadic template, even in C++03.
>> +
>> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
>> +#include <mutex>
>> +#include <typeinfo>
>> +#include <cassert>
>> +#include <iostream>
>> +
>> +int main() {
>> +    const std::string expect = "NSt3__110lock_guardIJNS_5mutexEEEE";
>> +    assert(typeid(std::lock_guard<std::mutex>).name() == expect);
>> +}
>>
>> Modified:
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp?rev=272634&r1=272633&r2=272634&view=diff
>>
>> ==============================================================================
>> ---
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp
>> (original)
>> +++
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp
>> Mon Jun 13 22:48:09 2016
>> @@ -7,6 +7,8 @@
>>  //
>>
>>  //===----------------------------------------------------------------------===//
>>
>> +// UNSUPPORTED: libcpp-has-no-threads
>> +
>>  // <mutex>
>>
>>  // template <class Mutex> class lock_guard;
>> @@ -14,35 +16,9 @@
>>  // explicit lock_guard(mutex_type& m);
>>
>>  #include <mutex>
>> -#include <thread>
>> -#include <cstdlib>
>> -#include <cassert>
>> -
>> -std::mutex m;
>> -
>> -typedef std::chrono::system_clock Clock;
>> -typedef Clock::time_point time_point;
>> -typedef Clock::duration duration;
>> -typedef std::chrono::milliseconds ms;
>> -typedef std::chrono::nanoseconds ns;
>> -
>> -void f()
>> -{
>> -    time_point t0 = Clock::now();
>> -    time_point t1;
>> -    {
>> -    std::lock_guard<std::mutex> lg = m;
>> -    t1 = Clock::now();
>> -    }
>> -    ns d = t1 - t0 - ms(250);
>> -    assert(d < ns(2500000));  // within 2.5ms
>> -}
>>
>>  int main()
>>  {
>> -    m.lock();
>> -    std::thread t(f);
>> -    std::this_thread::sleep_for(ms(250));
>> -    m.unlock();
>> -    t.join();
>> +    std::mutex m;
>> +    std::lock_guard<std::mutex> lg = m; // expected-error{{no viable
>> conversion}}
>>  }
>>
>> Added:
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp?rev=272634&view=auto
>>
>> ==============================================================================
>> ---
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp
>> (added)
>> +++
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp
>> Mon Jun 13 22:48:09 2016
>> @@ -0,0 +1,62 @@
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +//                     The LLVM Compiler Infrastructure
>> +//
>> +// This file is dual licensed under the MIT and the University of
>> Illinois Open
>> +// Source Licenses. See LICENSE.TXT for details.
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +// UNSUPPORTED: libcpp-has-no-threads
>> +// UNSUPPORTED: c++98, c++03
>> +
>> +// <mutex>
>> +
>> +// template <class ...Mutex> class lock_guard;
>> +
>> +// lock_guard(Mutex&..., adopt_lock_t);
>> +
>> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
>> +#include <mutex>
>> +#include <cassert>
>> +
>> +struct TestMutex {
>> +    bool locked = false;
>> +    TestMutex() = default;
>> +
>> +    void lock() { assert(!locked); locked = true; }
>> +    bool try_lock() { if (locked) return false; return locked = true; }
>> +    void unlock() { assert(locked); locked = false; }
>> +
>> +    TestMutex(TestMutex const&) = delete;
>> +    TestMutex& operator=(TestMutex const&) = delete;
>> +};
>> +
>> +int main()
>> +{
>> +    {
>> +        using LG = std::lock_guard<>;
>> +        LG lg(std::adopt_lock);
>> +    }
>> +    {
>> +        TestMutex m1, m2;
>> +        using LG = std::lock_guard<TestMutex, TestMutex>;
>> +        m1.lock(); m2.lock();
>> +        {
>> +            LG lg(m1, m2, std::adopt_lock);
>> +            assert(m1.locked && m2.locked);
>> +        }
>> +        assert(!m1.locked && !m2.locked);
>> +    }
>> +    {
>> +        TestMutex m1, m2, m3;
>> +        using LG = std::lock_guard<TestMutex, TestMutex, TestMutex>;
>> +        m1.lock(); m2.lock(); m3.lock();
>> +        {
>> +            LG lg(m1, m2, m3, std::adopt_lock);
>> +            assert(m1.locked && m2.locked && m3.locked);
>> +        }
>> +        assert(!m1.locked && !m2.locked && !m3.locked);
>> +    }
>> +
>> +}
>>
>> Added:
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp?rev=272634&view=auto
>>
>> ==============================================================================
>> ---
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp
>> (added)
>> +++
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp
>> Mon Jun 13 22:48:09 2016
>> @@ -0,0 +1,44 @@
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +//                     The LLVM Compiler Infrastructure
>> +//
>> +// This file is dual licensed under the MIT and the University of
>> Illinois Open
>> +// Source Licenses. See LICENSE.TXT for details.
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +
>> +// UNSUPPORTED: libcpp-has-no-threads
>> +// UNSUPPORTED: c++98, c++03
>> +
>> +// <mutex>
>> +
>> +// template <class ...Mutex> class lock_guard;
>> +
>> +// lock_guard& operator=(lock_guard const&) = delete;
>> +
>> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
>> +#include <mutex>
>> +
>> +int main()
>> +{
>> +    using M = std::mutex;
>> +    M m0, m1, m2;
>> +    M om0, om1, om2;
>> +    {
>> +        using LG = std::lock_guard<>;
>> +        LG lg1, lg2;
>> +        lg1 = lg2; // expected-error{{overload resolution selected
>> deleted operator '='}}
>> +    }
>> +    {
>> +        using LG = std::lock_guard<M, M>;
>> +        LG lg1(m0, m1);
>> +        LG lg2(om0, om1);
>> +        lg1 = lg2; // expected-error{{overload resolution selected
>> deleted operator '='}}
>> +    }
>> +    {
>> +        using LG = std::lock_guard<M, M, M>;
>> +        LG lg1(m0, m1, m2);
>> +        LG lg2(om0, om1, om2);
>> +        lg1 = lg2; // expected-error{{overload resolution selected
>> deleted operator '='}}
>> +    }
>> +}
>>
>> Added:
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp?rev=272634&view=auto
>>
>> ==============================================================================
>> ---
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp
>> (added)
>> +++
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp
>> Mon Jun 13 22:48:09 2016
>> @@ -0,0 +1,41 @@
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +//                     The LLVM Compiler Infrastructure
>> +//
>> +// This file is dual licensed under the MIT and the University of
>> Illinois Open
>> +// Source Licenses. See LICENSE.TXT for details.
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +
>> +// UNSUPPORTED: libcpp-has-no-threads
>> +// UNSUPPORTED: c++98, c++03
>> +
>> +// <mutex>
>> +
>> +// template <class ...Mutex> class lock_guard;
>> +
>> +// lock_guard(lock_guard const&) = delete;
>> +
>> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
>> +#include <mutex>
>> +
>> +int main()
>> +{
>> +    using M = std::mutex;
>> +    M m0, m1, m2;
>> +    {
>> +        using LG = std::lock_guard<>;
>> +        const LG Orig;
>> +        LG Copy(Orig); // expected-error{{call to deleted constructor of
>> 'LG'}}
>> +    }
>> +    {
>> +        using LG = std::lock_guard<M, M>;
>> +        const LG Orig(m0, m1);
>> +        LG Copy(Orig); // expected-error{{call to deleted constructor of
>> 'LG'}}
>> +    }
>> +    {
>> +        using LG = std::lock_guard<M, M, M>;
>> +        const LG Orig(m0, m1, m2);
>> +        LG Copy(Orig); // expected-error{{call to deleted constructor of
>> 'LG'}}
>> +    }
>> +}
>>
>> Added:
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp?rev=272634&view=auto
>>
>> ==============================================================================
>> ---
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp
>> (added)
>> +++
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp
>> Mon Jun 13 22:48:09 2016
>> @@ -0,0 +1,47 @@
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +//                     The LLVM Compiler Infrastructure
>> +//
>> +// This file is dual licensed under the MIT and the University of
>> Illinois Open
>> +// Source Licenses. See LICENSE.TXT for details.
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +
>> +// UNSUPPORTED: libcpp-has-no-threads
>> +// UNSUPPORTED: c++98, c++03
>> +
>> +// <mutex>
>> +
>> +// template <class ...Mutex> class lock_guard;
>> +
>> +// explicit lock_guard(Mutex&...);
>> +
>> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
>> +#include <mutex>
>> +
>> +template <class LG>
>> +void test_conversion(LG) {}
>> +
>> +int main()
>> +{
>> +    using M = std::mutex;
>> +    M m0, m1, m2;
>> +    M n0, n1, n2;
>> +    {
>> +        using LG = std::lock_guard<>;
>> +        LG lg = {}; // expected-error{{chosen constructor is explicit in
>> copy-initialization}}
>> +        test_conversion<LG>({}); // expected-error{{no matching function
>> for call}}
>> +        ((void)lg);
>> +    }
>> +    {
>> +        using LG = std::lock_guard<M, M>;
>> +        LG lg = {m0, m1}; // expected-error{{chosen constructor is
>> explicit in copy-initialization}}
>> +        test_conversion<LG>({n0, n1}); // expected-error{{no matching
>> function for call}}
>> +        ((void)lg);
>> +    }
>> +    {
>> +        using LG = std::lock_guard<M, M, M>;
>> +        LG lg = {m0, m1, m2}; // expected-error{{chosen constructor is
>> explicit in copy-initialization}}
>> +        test_conversion<LG>({n0, n1, n2}); // expected-error{{no
>> matching function for call}}
>> +    }
>> +}
>>
>> Added:
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp?rev=272634&view=auto
>>
>> ==============================================================================
>> ---
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp
>> (added)
>> +++
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp
>> Mon Jun 13 22:48:09 2016
>> @@ -0,0 +1,113 @@
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +//                     The LLVM Compiler Infrastructure
>> +//
>> +// This file is dual licensed under the MIT and the University of
>> Illinois Open
>> +// Source Licenses. See LICENSE.TXT for details.
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +// UNSUPPORTED: libcpp-has-no-threads
>> +// UNSUPPORTED: c++98, c++03
>> +
>> +// <mutex>
>> +
>> +// template <class ...Mutex> class lock_guard;
>> +
>> +// explicit lock_guard(mutex_type& m);
>> +
>> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
>> +#include <mutex>
>> +#include <cassert>
>> +
>> +struct TestMutex {
>> +    bool locked = false;
>> +    TestMutex() = default;
>> +    ~TestMutex() { assert(!locked); }
>> +
>> +    void lock() { assert(!locked); locked = true; }
>> +    bool try_lock() { if (locked) return false; return locked = true; }
>> +    void unlock() { assert(locked); locked = false; }
>> +
>> +    TestMutex(TestMutex const&) = delete;
>> +    TestMutex& operator=(TestMutex const&) = delete;
>> +};
>> +
>> +#if !defined(TEST_HAS_NO_EXCEPTIONS)
>> +struct TestMutexThrows {
>> +    bool locked = false;
>> +    bool throws_on_lock = false;
>> +
>> +    TestMutexThrows() = default;
>> +    ~TestMutexThrows() { assert(!locked); }
>> +
>> +    void lock() {
>> +        assert(!locked);
>> +        if (throws_on_lock) {
>> +            throw 42;
>> +        }
>> +        locked = true;
>> +    }
>> +
>> +    bool try_lock() {
>> +        if (locked) return false;
>> +        lock();
>> +        return true;
>> +    }
>> +
>> +    void unlock() { assert(locked); locked = false; }
>> +
>> +    TestMutexThrows(TestMutexThrows const&) = delete;
>> +    TestMutexThrows& operator=(TestMutexThrows const&) = delete;
>> +};
>> +#endif // !defined(TEST_HAS_NO_EXCEPTIONS)
>> +
>> +int main()
>> +{
>> +    {
>> +        using LG = std::lock_guard<>;
>> +        LG lg;
>> +    }
>> +    {
>> +        using LG = std::lock_guard<TestMutex, TestMutex>;
>> +        TestMutex m1, m2;
>> +        {
>> +            LG lg(m1, m2);
>> +            assert(m1.locked && m2.locked);
>> +        }
>> +        assert(!m1.locked && !m2.locked);
>> +    }
>> +    {
>> +        using LG = std::lock_guard<TestMutex, TestMutex, TestMutex>;
>> +        TestMutex m1, m2, m3;
>> +        {
>> +            LG lg(m1, m2, m3);
>> +            assert(m1.locked && m2.locked && m3.locked);
>> +        }
>> +        assert(!m1.locked && !m2.locked && !m3.locked);
>> +    }
>> +#if !defined(TEST_HAS_NO_EXCEPTIONS)
>> +    {
>> +        using MT = TestMutexThrows;
>> +        using LG = std::lock_guard<MT, MT>;
>> +        MT m1, m2;
>> +        m1.throws_on_lock = true;
>> +        try {
>> +            LG lg(m1, m2);
>> +            assert(false);
>> +        } catch (int) {}
>> +        assert(!m1.locked && !m2.locked);
>> +    }
>> +    {
>> +        using MT = TestMutexThrows;
>> +        using LG = std::lock_guard<MT, MT, MT>;
>> +        MT m1, m2, m3;
>> +        m2.throws_on_lock = true;
>> +        try {
>> +            LG lg(m1, m2, m3);
>> +            assert(false);
>> +        } catch (int) {}
>> +        assert(!m1.locked && !m2.locked && !m3.locked);
>> +    }
>> +#endif
>> +}
>>
>> Added:
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp?rev=272634&view=auto
>>
>> ==============================================================================
>> ---
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp
>> (added)
>> +++
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp
>> Mon Jun 13 22:48:09 2016
>> @@ -0,0 +1,21 @@
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +//                     The LLVM Compiler Infrastructure
>> +//
>> +// This file is dual licensed under the MIT and the University of
>> Illinois Open
>> +// Source Licenses. See LICENSE.TXT for details.
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +// UNSUPPORTED: libcpp-has-no-threads
>> +
>> +// <mutex>
>> +
>> +// template <class ...Mutex> class lock_guard;
>> +
>> +// Test that the variadic lock guard implementation compiles in all
>> standard
>> +// dialects, including C++03, even though it is forward declared using
>> +// variadic templates.
>> +
>> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
>> +#include "mutex.pass.cpp" // Use the existing non-variadic test
>>
>> Added:
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp?rev=272634&view=auto
>>
>> ==============================================================================
>> ---
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp
>> (added)
>> +++
>> libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp
>> Mon Jun 13 22:48:09 2016
>> @@ -0,0 +1,78 @@
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +//                     The LLVM Compiler Infrastructure
>> +//
>> +// This file is dual licensed under the MIT and the University of
>> Illinois Open
>> +// Source Licenses. See LICENSE.TXT for details.
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +// UNSUPPORTED: libcpp-has-no-threads
>> +// UNSUPPORTED: c++98, c++03
>> +
>> +// <mutex>
>> +
>> +// template <class Mutex>
>> +// class lock_guard
>> +// {
>> +// public:
>> +//     typedef Mutex mutex_type;
>> +//     ...
>> +// };
>> +
>> +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
>> +#include <mutex>
>> +#include <type_traits>
>> +
>> +struct NAT {};
>> +
>> +template <class LG>
>> +auto test_typedef(int) -> typename LG::mutex_type;
>> +
>> +template <class LG>
>> +auto test_typedef(...) -> NAT;
>> +
>> +template <class LG>
>> +constexpr bool has_mutex_type() {
>> +    return !std::is_same<decltype(test_typedef<LG>(0)), NAT>::value;
>> +}
>> +
>> +int main()
>> +{
>> +    {
>> +        using T = std::lock_guard<>;
>> +        static_assert(!has_mutex_type<T>(), "");
>> +    }
>> +    {
>> +        using M1 = std::mutex;
>> +        using T = std::lock_guard<M1>;
>> +        static_assert(std::is_same<T::mutex_type, M1>::value, "");
>> +    }
>> +    {
>> +        using M1 = std::recursive_mutex;
>> +        using T = std::lock_guard<M1>;
>> +        static_assert(std::is_same<T::mutex_type, M1>::value, "");
>> +    }
>> +    {
>> +        using M1 = std::mutex;
>> +        using M2 = std::recursive_mutex;
>> +        using T = std::lock_guard<M1, M2>;
>> +        static_assert(!has_mutex_type<T>(), "");
>> +    }
>> +    {
>> +        using M1 = std::mutex;
>> +        using M2 = std::recursive_mutex;
>> +        using T = std::lock_guard<M1, M1, M2>;
>> +        static_assert(!has_mutex_type<T>(), "");
>> +    }
>> +    {
>> +        using M1 = std::mutex;
>> +        using T = std::lock_guard<M1, M1>;
>> +        static_assert(!has_mutex_type<T>(), "");
>> +    }
>> +    {
>> +        using M1 = std::recursive_mutex;
>> +        using T = std::lock_guard<M1, M1, M1>;
>> +        static_assert(!has_mutex_type<T>(), "");
>> +    }
>> +}
>>
>> Modified: libcxx/trunk/www/cxx1z_status.html
>> URL:
>> http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/cxx1z_status.html?rev=272634&r1=272633&r2=272634&view=diff
>>
>> ==============================================================================
>> --- libcxx/trunk/www/cxx1z_status.html (original)
>> +++ libcxx/trunk/www/cxx1z_status.html Mon Jun 13 22:48:09 2016
>> @@ -74,7 +74,7 @@
>>         <tr><td><a href="
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0006R0.html">P0006R0</a></td><td>LWG</td><td>Adopt
>> Type Traits Variable Templates for
>> C++17.</td><td>Kona</td><td>Complete</td><td>3.8</td></tr>
>>         <tr><td><a href="
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0092R1.html">P0092R1</a></td><td>LWG</td><td>Polishing
>> <chrono></td><td>Kona</td><td>Complete</td><td>3.8</td></tr>
>>         <tr><td><a href="
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0007R1.html">P0007R1</a></td><td>LWG</td><td>Constant
>> View: A proposal for a <tt>std::as_const</tt> helper function
>> template.</td><td>Kona</td><td>Complete</td><td>3.8</td></tr>
>> -       <tr><td><a href="
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0156R0.htm"
>> >P0156R0</a></td><td>LWG</td><td>Variadic lock_guard(rev
>> 3).</td><td>Kona</td><td></td><td></td></tr>
>> +       <tr><td><a href="
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0156r0.html"
>> >P0156R0</a></td><td>LWG</td><td>Variadic lock_guard(rev
>> 3).</td><td>Kona</td><td>Complete (ABI V2 Only)</td><td>3.9</td></tr>
>>         <tr><td><a href="
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0074R0.html">P0074R0</a></td><td>LWG</td><td>Making
>> <tt>std::owner_less</tt> more
>> flexible</td><td>Kona</td><td>Complete</td><td>3.8</td></tr>
>>         <tr><td><a href="
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0013R1.html">P0013R1</a></td><td>LWG</td><td>Logical
>> type traits rev 2</td><td>Kona</td><td>Complete</td><td>3.8</td></tr>
>>         <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr>
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160614/92558c89/attachment-0001.html>


More information about the cfe-commits mailing list