[libcxx] r272634 - Implement variadic lock_guard.
Eric Fiselier via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 15 11:15:53 PDT 2016
On Wed, Jun 15, 2016 at 11:45 AM, Craig, Ben via cfe-commits <
cfe-commits at lists.llvm.org> wrote:
> 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.
>
I had no idea that syntax did that. I would have assumed it created an
unnamed temporary. I can see how that would cause bugs.
> 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?
>
Nothing in the spec says the empty template should be undefined. The
default constructor on the empty template is technically implementing
"lock_guard(MutexTypes...)" for an empty pack.
However your example provides ample motivation to make it undefined. I'll
go ahead and make that change and I'll file a LWG defect to change the
standard.
There is actually no recursion in the variadic lock_guard implementation,
so the change is trivial.
As for mangling I'm not sure what you mean? It definitely doesn't change
the fact that this change is ABI breaking. (Note this change is not enabled
by default for that reason).
>
> 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 <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>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>
>>> 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>
>>> 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>
>>> 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>
>>> 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>
>>> 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>
>>> 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>
>>> 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
>>>
>>
>>
>
>
> _______________________________________________
> cfe-commits mailing listcfe-commits at lists.llvm.orghttp://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 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/20160615/d1441479/attachment-0001.html>
More information about the cfe-commits
mailing list