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> 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@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