Does this change (and the paper) permit declarations like the following?

    lock_guard<> guard();

If that syntax is allowed, then this is also likely allowed...

    lock_guard<>(guard);

I would really like the prior two examples to not compile. Here is a common bug that I see in the wild...

    unique_guard<mutex>(some_member_mutex);

That defines a new, default constructed unique_guard named "some_member_mutex", that likely shadows the member variable some_member_mutex. It is almost never what users want.

Is it possible to have the empty template remain undefined, and let the one element lock_guard be the base case of the recursion? Does that help any with the mangling?


On 6/14/2016 8:24 PM, Eric Fiselier via cfe-commits wrote:
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 <e...@efcs.ca <mailto:e...@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@lists.llvm.org <mailto:cfe-commits@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
        &lt;chrono&gt;</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@lists.llvm.org <mailto:cfe-commits@lists.llvm.org>
        http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits





_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux 
Foundation Collaborative Project

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to