<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p>Does this change (and the paper) permit declarations like the
following?</p>
<p> lock_guard<> guard();</p>
<p>If that syntax is allowed, then this is also likely allowed...</p>
<p> lock_guard<>(guard);</p>
<p>I would really like the prior two examples to not compile. Here
is a common bug that I see in the wild...</p>
<p> unique_guard<mutex>(some_member_mutex);</p>
<p>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.<br>
</p>
<p>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?<br>
</p>
<br>
<div class="moz-cite-prefix">On 6/14/2016 8:24 PM, Eric Fiselier via
cfe-commits wrote:<br>
</div>
<blockquote
cite="mid:CAB=TDAUfaVg1d4fDSnLQNe5Htby87sYC8QXCXRUcseS073yKLA@mail.gmail.com"
type="cite">
<div dir="ltr">
<div>Update on the bot failures:</div>
<div><br>
</div>
I've spoken to the owner of the bots and they are planning to
upgrade their Clang versions.
<div>This will get the bots green again.</div>
<div><br>
</div>
<div>/Eric</div>
</div>
<div class="gmail_extra"><br>
<div class="gmail_quote">On Mon, Jun 13, 2016 at 11:49 PM, Eric
Fiselier <span dir="ltr"><<a moz-do-not-send="true"
href="mailto:eric@efcs.ca" target="_blank">eric@efcs.ca</a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">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.
<div>The test passes against current ToT and older clang
releases and GCC.</div>
<div><br>
</div>
<div>Please do not revert this commit due to that specific
failure. I am aware of it and I am working to fix it.</div>
</div>
<div class="HOEnZb">
<div class="h5">
<div class="gmail_extra"><br>
<div class="gmail_quote">On Mon, Jun 13, 2016 at 9:48
PM, Eric Fiselier via cfe-commits <span dir="ltr"><<a
moz-do-not-send="true"
href="mailto:cfe-commits@lists.llvm.org"
target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a></a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">Author:
ericwf<br>
Date: Mon Jun 13 22:48:09 2016<br>
New Revision: 272634<br>
<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project?rev=272634&view=rev"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=272634&view=rev</a><br>
Log:<br>
Implement variadic lock_guard.<br>
<br>
Summary:<br>
This patch implements the variadic `lock_guard`
paper.<br>
<br>
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.<br>
<br>
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.<br>
<br>
<br>
<br>
<br>
Reviewers: mclow.lists<br>
<br>
Subscribers: K-ballo, mclow.lists, cfe-commits<br>
<br>
Differential Revision: <a moz-do-not-send="true"
href="http://reviews.llvm.org/D21260"
rel="noreferrer" target="_blank">http://reviews.llvm.org/D21260</a><br>
<br>
Added:<br>
libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/<br>
libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/<br>
libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp<br>
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp<br>
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp<br>
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp<br>
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp<br>
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp<br>
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp<br>
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp<br>
Modified:<br>
libcxx/trunk/include/__config<br>
libcxx/trunk/include/__mutex_base<br>
libcxx/trunk/include/mutex<br>
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp<br>
libcxx/trunk/www/cxx1z_status.html<br>
<br>
Modified: libcxx/trunk/include/__config<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=272634&r1=272633&r2=272634&view=diff"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=272634&r1=272633&r2=272634&view=diff</a><br>
==============================================================================<br>
--- libcxx/trunk/include/__config (original)<br>
+++ libcxx/trunk/include/__config Mon Jun 13
22:48:09 2016<br>
@@ -43,6 +43,7 @@<br>
#define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB<br>
#define
_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB<br>
#define
_LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE<br>
+#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD<br>
#endif<br>
<br>
#define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y)
_LIBCPP_X##_LIBCPP_Y<br>
<br>
Modified: libcxx/trunk/include/__mutex_base<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__mutex_base?rev=272634&r1=272633&r2=272634&view=diff"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__mutex_base?rev=272634&r1=272633&r2=272634&view=diff</a><br>
==============================================================================<br>
--- libcxx/trunk/include/__mutex_base (original)<br>
+++ libcxx/trunk/include/__mutex_base Mon Jun 13
22:48:09 2016<br>
@@ -76,8 +76,21 @@ constexpr adopt_lock_t
adopt_lock = ad<br>
<br>
#endif<br>
<br>
+<br>
+// Forward declare lock_guard as a variadic
template even in C++03 to keep<br>
+// the mangling consistent between dialects.<br>
+#if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD)<br>
+template <class ..._Mutexes><br>
+class _LIBCPP_TYPE_VIS_ONLY lock_guard;<br>
+#endif<br>
+<br>
template <class _Mutex><br>
-class _LIBCPP_TYPE_VIS_ONLY
_LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable)
lock_guard<br>
+class _LIBCPP_TYPE_VIS_ONLY
_LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable)<br>
+#if !defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD)<br>
+lock_guard<br>
+#else<br>
+lock_guard<_Mutex><br>
+#endif<br>
{<br>
public:<br>
typedef _Mutex mutex_type;<br>
@@ -96,8 +109,8 @@ public:<br>
~lock_guard()
_LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability())
{__m_.unlock();}<br>
<br>
private:<br>
- lock_guard(lock_guard const&);// =
delete;<br>
- lock_guard& operator=(lock_guard
const&);// = delete;<br>
+ lock_guard(lock_guard const&)
_LIBCPP_EQUAL_DELETE;<br>
+ lock_guard& operator=(lock_guard
const&) _LIBCPP_EQUAL_DELETE;<br>
};<br>
<br>
template <class _Mutex><br>
<br>
Modified: libcxx/trunk/include/mutex<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/mutex?rev=272634&r1=272633&r2=272634&view=diff"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/mutex?rev=272634&r1=272633&r2=272634&view=diff</a><br>
==============================================================================<br>
--- libcxx/trunk/include/mutex (original)<br>
+++ libcxx/trunk/include/mutex Mon Jun 13 22:48:09
2016<br>
@@ -109,6 +109,19 @@ public:<br>
lock_guard& operator=(lock_guard
const&) = delete;<br>
};<br>
<br>
+template <class... MutexTypes> // Variadic
lock_guard only provided in ABI V2.<br>
+class lock_guard<br>
+{<br>
+public:<br>
+ explicit lock_guard(MutexTypes&... m);<br>
+ lock_guard(MutexTypes&... m,
adopt_lock_t);<br>
+ ~lock_guard();<br>
+ lock_guard(lock_guard const&) = delete;<br>
+ lock_guard& operator=(lock_guard
const&) = delete;<br>
+private:<br>
+ tuple<MutexTypes&...> pm; //
exposition only<br>
+};<br>
+<br>
template <class Mutex><br>
class unique_lock<br>
{<br>
@@ -427,6 +440,27 @@ lock(_L0& __l0, _L1&
__l1, _L2& __l2, _L<br>
__lock_first(0, __l0, __l1, __l2, __l3...);<br>
}<br>
<br>
+template <class _L0><br>
+inline _LIBCPP_INLINE_VISIBILITY<br>
+void __unlock(_L0& __l0) {<br>
+ __l0.unlock();<br>
+}<br>
+<br>
+template <class _L0, class _L1><br>
+inline _LIBCPP_INLINE_VISIBILITY<br>
+void __unlock(_L0& __l0, _L1& __l1) {<br>
+ __l0.unlock();<br>
+ __l1.unlock();<br>
+}<br>
+<br>
+template <class _L0, class _L1, class _L2,
class ..._L3><br>
+inline _LIBCPP_INLINE_VISIBILITY<br>
+void __unlock(_L0& __l0, _L1& __l1,
_L2& __l2, _L3&... __l3) {<br>
+ __l0.unlock();<br>
+ __l1.unlock();<br>
+ _VSTD::__unlock(__l2, __l3...);<br>
+}<br>
+<br>
#endif // _LIBCPP_HAS_NO_VARIADICS<br>
<br>
#endif // !_LIBCPP_HAS_NO_THREADS<br>
@@ -577,6 +611,63 @@ call_once(once_flag&
__flag, const _Call<br>
<br>
#endif // _LIBCPP_HAS_NO_VARIADICS<br>
<br>
+<br>
+#if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD) \<br>
+ && !defined(_LIBCPP_CXX03_LANG)<br>
+template <><br>
+class _LIBCPP_TYPE_VIS_ONLY lock_guard<> {<br>
+public:<br>
+ explicit lock_guard() = default;<br>
+ ~lock_guard() = default;<br>
+<br>
+ _LIBCPP_INLINE_VISIBILITY<br>
+ explicit lock_guard(adopt_lock_t) {}<br>
+<br>
+ lock_guard(lock_guard const&) = delete;<br>
+ lock_guard& operator=(lock_guard
const&) = delete;<br>
+};<br>
+<br>
+template <class ..._MArgs><br>
+class _LIBCPP_TYPE_VIS_ONLY lock_guard<br>
+{<br>
+ static_assert(sizeof...(_MArgs) >= 2, "At
least 2 lock types required");<br>
+ typedef tuple<_MArgs&...>
_MutexTuple;<br>
+<br>
+public:<br>
+ _LIBCPP_INLINE_VISIBILITY<br>
+ explicit lock_guard(_MArgs&... __margs)<br>
+ : __t_(__margs...)<br>
+ {<br>
+ _VSTD::lock(__margs...);<br>
+ }<br>
+<br>
+ _LIBCPP_INLINE_VISIBILITY<br>
+ lock_guard(_MArgs&... __margs,
adopt_lock_t)<br>
+ : __t_(__margs...)<br>
+ {<br>
+ }<br>
+<br>
+ _LIBCPP_INLINE_VISIBILITY<br>
+ ~lock_guard() {<br>
+ typedef typename
__make_tuple_indices<sizeof...(_MArgs)>::type
_Indices;<br>
+ __unlock_unpack(_Indices{}, __t_);<br>
+ }<br>
+<br>
+ lock_guard(lock_guard const&) = delete;<br>
+ lock_guard& operator=(lock_guard
const&) = delete;<br>
+<br>
+private:<br>
+ template <size_t ..._Indx><br>
+ _LIBCPP_INLINE_VISIBILITY<br>
+ static void
__unlock_unpack(__tuple_indices<_Indx...>,
_MutexTuple& __mt) {<br>
+
_VSTD::__unlock(_VSTD::get<_Indx>(__mt)...);<br>
+ }<br>
+<br>
+ _MutexTuple __t_;<br>
+};<br>
+<br>
+#endif // _LIBCPP_ABI_VARIADIC_LOCK_GUARD<br>
+<br>
_LIBCPP_END_NAMESPACE_STD<br>
<br>
#endif // _LIBCPP_MUTEX<br>
<br>
Added:
libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp<br>
URL: <a moz-do-not-send="true"
href="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"
rel="noreferrer" target="_blank">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</a><br>
==============================================================================<br>
---
libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp
(added)<br>
+++
libcxx/trunk/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp
Mon Jun 13 22:48:09 2016<br>
@@ -0,0 +1,31 @@<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// The LLVM Compiler
Infrastructure<br>
+//<br>
+// This file is dual licensed under the MIT and
the University of Illinois Open<br>
+// Source Licenses. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// UNSUPPORTED: libcpp-has-no-threads<br>
+<br>
+// THIS TESTS C++03 EXTENSIONS.<br>
+<br>
+// <mutex><br>
+<br>
+// template <class ...Mutex> class
lock_guard;<br>
+<br>
+// Test that the the variadic lock guard
implementation mangles the same in<br>
+// C++11 and C++03. This is important since the
mangling of `lock_guard` depends<br>
+// on it being declared as a variadic template,
even in C++03.<br>
+<br>
+#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD<br>
+#include <mutex><br>
+#include <typeinfo><br>
+#include <cassert><br>
+#include <iostream><br>
+<br>
+int main() {<br>
+ const std::string expect =
"NSt3__110lock_guardIJNS_5mutexEEEE";<br>
+
assert(typeid(std::lock_guard<std::mutex>).name()
== expect);<br>
+}<br>
<br>
Modified:
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp<br>
URL: <a moz-do-not-send="true"
href="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"
rel="noreferrer" target="_blank">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</a><br>
==============================================================================<br>
---
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp
(original)<br>
+++
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp
Mon Jun 13 22:48:09 2016<br>
@@ -7,6 +7,8 @@<br>
//<br>
//===----------------------------------------------------------------------===//<br>
<br>
+// UNSUPPORTED: libcpp-has-no-threads<br>
+<br>
// <mutex><br>
<br>
// template <class Mutex> class lock_guard;<br>
@@ -14,35 +16,9 @@<br>
// explicit lock_guard(mutex_type& m);<br>
<br>
#include <mutex><br>
-#include <thread><br>
-#include <cstdlib><br>
-#include <cassert><br>
-<br>
-std::mutex m;<br>
-<br>
-typedef std::chrono::system_clock Clock;<br>
-typedef Clock::time_point time_point;<br>
-typedef Clock::duration duration;<br>
-typedef std::chrono::milliseconds ms;<br>
-typedef std::chrono::nanoseconds ns;<br>
-<br>
-void f()<br>
-{<br>
- time_point t0 = Clock::now();<br>
- time_point t1;<br>
- {<br>
- std::lock_guard<std::mutex> lg = m;<br>
- t1 = Clock::now();<br>
- }<br>
- ns d = t1 - t0 - ms(250);<br>
- assert(d < ns(2500000)); // within 2.5ms<br>
-}<br>
<br>
int main()<br>
{<br>
- m.lock();<br>
- std::thread t(f);<br>
- std::this_thread::sleep_for(ms(250));<br>
- m.unlock();<br>
- t.join();<br>
+ std::mutex m;<br>
+ std::lock_guard<std::mutex> lg = m; //
expected-error{{no viable conversion}}<br>
}<br>
<br>
Added:
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp<br>
URL: <a moz-do-not-send="true"
href="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"
rel="noreferrer" target="_blank">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</a><br>
==============================================================================<br>
---
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp
(added)<br>
+++
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp
Mon Jun 13 22:48:09 2016<br>
@@ -0,0 +1,62 @@<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// The LLVM Compiler
Infrastructure<br>
+//<br>
+// This file is dual licensed under the MIT and
the University of Illinois Open<br>
+// Source Licenses. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// UNSUPPORTED: libcpp-has-no-threads<br>
+// UNSUPPORTED: c++98, c++03<br>
+<br>
+// <mutex><br>
+<br>
+// template <class ...Mutex> class
lock_guard;<br>
+<br>
+// lock_guard(Mutex&..., adopt_lock_t);<br>
+<br>
+#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD<br>
+#include <mutex><br>
+#include <cassert><br>
+<br>
+struct TestMutex {<br>
+ bool locked = false;<br>
+ TestMutex() = default;<br>
+<br>
+ void lock() { assert(!locked); locked = true;
}<br>
+ bool try_lock() { if (locked) return false;
return locked = true; }<br>
+ void unlock() { assert(locked); locked =
false; }<br>
+<br>
+ TestMutex(TestMutex const&) = delete;<br>
+ TestMutex& operator=(TestMutex
const&) = delete;<br>
+};<br>
+<br>
+int main()<br>
+{<br>
+ {<br>
+ using LG = std::lock_guard<>;<br>
+ LG lg(std::adopt_lock);<br>
+ }<br>
+ {<br>
+ TestMutex m1, m2;<br>
+ using LG = std::lock_guard<TestMutex,
TestMutex>;<br>
+ m1.lock(); m2.lock();<br>
+ {<br>
+ LG lg(m1, m2, std::adopt_lock);<br>
+ assert(m1.locked &&
m2.locked);<br>
+ }<br>
+ assert(!m1.locked && !m2.locked);<br>
+ }<br>
+ {<br>
+ TestMutex m1, m2, m3;<br>
+ using LG = std::lock_guard<TestMutex,
TestMutex, TestMutex>;<br>
+ m1.lock(); m2.lock(); m3.lock();<br>
+ {<br>
+ LG lg(m1, m2, m3, std::adopt_lock);<br>
+ assert(m1.locked && m2.locked
&& m3.locked);<br>
+ }<br>
+ assert(!m1.locked && !m2.locked
&& !m3.locked);<br>
+ }<br>
+<br>
+}<br>
<br>
Added:
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp<br>
URL: <a moz-do-not-send="true"
href="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"
rel="noreferrer" target="_blank">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</a><br>
==============================================================================<br>
---
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp
(added)<br>
+++
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp
Mon Jun 13 22:48:09 2016<br>
@@ -0,0 +1,44 @@<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// The LLVM Compiler
Infrastructure<br>
+//<br>
+// This file is dual licensed under the MIT and
the University of Illinois Open<br>
+// Source Licenses. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+// UNSUPPORTED: libcpp-has-no-threads<br>
+// UNSUPPORTED: c++98, c++03<br>
+<br>
+// <mutex><br>
+<br>
+// template <class ...Mutex> class
lock_guard;<br>
+<br>
+// lock_guard& operator=(lock_guard
const&) = delete;<br>
+<br>
+#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD<br>
+#include <mutex><br>
+<br>
+int main()<br>
+{<br>
+ using M = std::mutex;<br>
+ M m0, m1, m2;<br>
+ M om0, om1, om2;<br>
+ {<br>
+ using LG = std::lock_guard<>;<br>
+ LG lg1, lg2;<br>
+ lg1 = lg2; // expected-error{{overload
resolution selected deleted operator '='}}<br>
+ }<br>
+ {<br>
+ using LG = std::lock_guard<M, M>;<br>
+ LG lg1(m0, m1);<br>
+ LG lg2(om0, om1);<br>
+ lg1 = lg2; // expected-error{{overload
resolution selected deleted operator '='}}<br>
+ }<br>
+ {<br>
+ using LG = std::lock_guard<M, M,
M>;<br>
+ LG lg1(m0, m1, m2);<br>
+ LG lg2(om0, om1, om2);<br>
+ lg1 = lg2; // expected-error{{overload
resolution selected deleted operator '='}}<br>
+ }<br>
+}<br>
<br>
Added:
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp<br>
URL: <a moz-do-not-send="true"
href="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"
rel="noreferrer" target="_blank">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</a><br>
==============================================================================<br>
---
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp
(added)<br>
+++
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp
Mon Jun 13 22:48:09 2016<br>
@@ -0,0 +1,41 @@<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// The LLVM Compiler
Infrastructure<br>
+//<br>
+// This file is dual licensed under the MIT and
the University of Illinois Open<br>
+// Source Licenses. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+// UNSUPPORTED: libcpp-has-no-threads<br>
+// UNSUPPORTED: c++98, c++03<br>
+<br>
+// <mutex><br>
+<br>
+// template <class ...Mutex> class
lock_guard;<br>
+<br>
+// lock_guard(lock_guard const&) = delete;<br>
+<br>
+#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD<br>
+#include <mutex><br>
+<br>
+int main()<br>
+{<br>
+ using M = std::mutex;<br>
+ M m0, m1, m2;<br>
+ {<br>
+ using LG = std::lock_guard<>;<br>
+ const LG Orig;<br>
+ LG Copy(Orig); // expected-error{{call to
deleted constructor of 'LG'}}<br>
+ }<br>
+ {<br>
+ using LG = std::lock_guard<M, M>;<br>
+ const LG Orig(m0, m1);<br>
+ LG Copy(Orig); // expected-error{{call to
deleted constructor of 'LG'}}<br>
+ }<br>
+ {<br>
+ using LG = std::lock_guard<M, M,
M>;<br>
+ const LG Orig(m0, m1, m2);<br>
+ LG Copy(Orig); // expected-error{{call to
deleted constructor of 'LG'}}<br>
+ }<br>
+}<br>
<br>
Added:
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp<br>
URL: <a moz-do-not-send="true"
href="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"
rel="noreferrer" target="_blank">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</a><br>
==============================================================================<br>
---
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp
(added)<br>
+++
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp
Mon Jun 13 22:48:09 2016<br>
@@ -0,0 +1,47 @@<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// The LLVM Compiler
Infrastructure<br>
+//<br>
+// This file is dual licensed under the MIT and
the University of Illinois Open<br>
+// Source Licenses. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+// UNSUPPORTED: libcpp-has-no-threads<br>
+// UNSUPPORTED: c++98, c++03<br>
+<br>
+// <mutex><br>
+<br>
+// template <class ...Mutex> class
lock_guard;<br>
+<br>
+// explicit lock_guard(Mutex&...);<br>
+<br>
+#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD<br>
+#include <mutex><br>
+<br>
+template <class LG><br>
+void test_conversion(LG) {}<br>
+<br>
+int main()<br>
+{<br>
+ using M = std::mutex;<br>
+ M m0, m1, m2;<br>
+ M n0, n1, n2;<br>
+ {<br>
+ using LG = std::lock_guard<>;<br>
+ LG lg = {}; // expected-error{{chosen
constructor is explicit in copy-initialization}}<br>
+ test_conversion<LG>({}); //
expected-error{{no matching function for call}}<br>
+ ((void)lg);<br>
+ }<br>
+ {<br>
+ using LG = std::lock_guard<M, M>;<br>
+ LG lg = {m0, m1}; //
expected-error{{chosen constructor is explicit in
copy-initialization}}<br>
+ test_conversion<LG>({n0, n1}); //
expected-error{{no matching function for call}}<br>
+ ((void)lg);<br>
+ }<br>
+ {<br>
+ using LG = std::lock_guard<M, M,
M>;<br>
+ LG lg = {m0, m1, m2}; //
expected-error{{chosen constructor is explicit in
copy-initialization}}<br>
+ test_conversion<LG>({n0, n1, n2});
// expected-error{{no matching function for call}}<br>
+ }<br>
+}<br>
<br>
Added:
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp<br>
URL: <a moz-do-not-send="true"
href="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"
rel="noreferrer" target="_blank">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</a><br>
==============================================================================<br>
---
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp
(added)<br>
+++
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp
Mon Jun 13 22:48:09 2016<br>
@@ -0,0 +1,113 @@<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// The LLVM Compiler
Infrastructure<br>
+//<br>
+// This file is dual licensed under the MIT and
the University of Illinois Open<br>
+// Source Licenses. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// UNSUPPORTED: libcpp-has-no-threads<br>
+// UNSUPPORTED: c++98, c++03<br>
+<br>
+// <mutex><br>
+<br>
+// template <class ...Mutex> class
lock_guard;<br>
+<br>
+// explicit lock_guard(mutex_type& m);<br>
+<br>
+#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD<br>
+#include <mutex><br>
+#include <cassert><br>
+<br>
+struct TestMutex {<br>
+ bool locked = false;<br>
+ TestMutex() = default;<br>
+ ~TestMutex() { assert(!locked); }<br>
+<br>
+ void lock() { assert(!locked); locked = true;
}<br>
+ bool try_lock() { if (locked) return false;
return locked = true; }<br>
+ void unlock() { assert(locked); locked =
false; }<br>
+<br>
+ TestMutex(TestMutex const&) = delete;<br>
+ TestMutex& operator=(TestMutex
const&) = delete;<br>
+};<br>
+<br>
+#if !defined(TEST_HAS_NO_EXCEPTIONS)<br>
+struct TestMutexThrows {<br>
+ bool locked = false;<br>
+ bool throws_on_lock = false;<br>
+<br>
+ TestMutexThrows() = default;<br>
+ ~TestMutexThrows() { assert(!locked); }<br>
+<br>
+ void lock() {<br>
+ assert(!locked);<br>
+ if (throws_on_lock) {<br>
+ throw 42;<br>
+ }<br>
+ locked = true;<br>
+ }<br>
+<br>
+ bool try_lock() {<br>
+ if (locked) return false;<br>
+ lock();<br>
+ return true;<br>
+ }<br>
+<br>
+ void unlock() { assert(locked); locked =
false; }<br>
+<br>
+ TestMutexThrows(TestMutexThrows const&) =
delete;<br>
+ TestMutexThrows&
operator=(TestMutexThrows const&) = delete;<br>
+};<br>
+#endif // !defined(TEST_HAS_NO_EXCEPTIONS)<br>
+<br>
+int main()<br>
+{<br>
+ {<br>
+ using LG = std::lock_guard<>;<br>
+ LG lg;<br>
+ }<br>
+ {<br>
+ using LG = std::lock_guard<TestMutex,
TestMutex>;<br>
+ TestMutex m1, m2;<br>
+ {<br>
+ LG lg(m1, m2);<br>
+ assert(m1.locked &&
m2.locked);<br>
+ }<br>
+ assert(!m1.locked && !m2.locked);<br>
+ }<br>
+ {<br>
+ using LG = std::lock_guard<TestMutex,
TestMutex, TestMutex>;<br>
+ TestMutex m1, m2, m3;<br>
+ {<br>
+ LG lg(m1, m2, m3);<br>
+ assert(m1.locked && m2.locked
&& m3.locked);<br>
+ }<br>
+ assert(!m1.locked && !m2.locked
&& !m3.locked);<br>
+ }<br>
+#if !defined(TEST_HAS_NO_EXCEPTIONS)<br>
+ {<br>
+ using MT = TestMutexThrows;<br>
+ using LG = std::lock_guard<MT, MT>;<br>
+ MT m1, m2;<br>
+ m1.throws_on_lock = true;<br>
+ try {<br>
+ LG lg(m1, m2);<br>
+ assert(false);<br>
+ } catch (int) {}<br>
+ assert(!m1.locked && !m2.locked);<br>
+ }<br>
+ {<br>
+ using MT = TestMutexThrows;<br>
+ using LG = std::lock_guard<MT, MT,
MT>;<br>
+ MT m1, m2, m3;<br>
+ m2.throws_on_lock = true;<br>
+ try {<br>
+ LG lg(m1, m2, m3);<br>
+ assert(false);<br>
+ } catch (int) {}<br>
+ assert(!m1.locked && !m2.locked
&& !m3.locked);<br>
+ }<br>
+#endif<br>
+}<br>
<br>
Added:
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp<br>
URL: <a moz-do-not-send="true"
href="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"
rel="noreferrer" target="_blank">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</a><br>
==============================================================================<br>
---
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp
(added)<br>
+++
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp
Mon Jun 13 22:48:09 2016<br>
@@ -0,0 +1,21 @@<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// The LLVM Compiler
Infrastructure<br>
+//<br>
+// This file is dual licensed under the MIT and
the University of Illinois Open<br>
+// Source Licenses. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// UNSUPPORTED: libcpp-has-no-threads<br>
+<br>
+// <mutex><br>
+<br>
+// template <class ...Mutex> class
lock_guard;<br>
+<br>
+// Test that the variadic lock guard
implementation compiles in all standard<br>
+// dialects, including C++03, even though it is
forward declared using<br>
+// variadic templates.<br>
+<br>
+#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD<br>
+#include "mutex.pass.cpp" // Use the existing
non-variadic test<br>
<br>
Added:
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp<br>
URL: <a moz-do-not-send="true"
href="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"
rel="noreferrer" target="_blank">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</a><br>
==============================================================================<br>
---
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp
(added)<br>
+++
libcxx/trunk/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp
Mon Jun 13 22:48:09 2016<br>
@@ -0,0 +1,78 @@<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// The LLVM Compiler
Infrastructure<br>
+//<br>
+// This file is dual licensed under the MIT and
the University of Illinois Open<br>
+// Source Licenses. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// UNSUPPORTED: libcpp-has-no-threads<br>
+// UNSUPPORTED: c++98, c++03<br>
+<br>
+// <mutex><br>
+<br>
+// template <class Mutex><br>
+// class lock_guard<br>
+// {<br>
+// public:<br>
+// typedef Mutex mutex_type;<br>
+// ...<br>
+// };<br>
+<br>
+#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD<br>
+#include <mutex><br>
+#include <type_traits><br>
+<br>
+struct NAT {};<br>
+<br>
+template <class LG><br>
+auto test_typedef(int) -> typename
LG::mutex_type;<br>
+<br>
+template <class LG><br>
+auto test_typedef(...) -> NAT;<br>
+<br>
+template <class LG><br>
+constexpr bool has_mutex_type() {<br>
+ return
!std::is_same<decltype(test_typedef<LG>(0)),
NAT>::value;<br>
+}<br>
+<br>
+int main()<br>
+{<br>
+ {<br>
+ using T = std::lock_guard<>;<br>
+ static_assert(!has_mutex_type<T>(),
"");<br>
+ }<br>
+ {<br>
+ using M1 = std::mutex;<br>
+ using T = std::lock_guard<M1>;<br>
+
static_assert(std::is_same<T::mutex_type,
M1>::value, "");<br>
+ }<br>
+ {<br>
+ using M1 = std::recursive_mutex;<br>
+ using T = std::lock_guard<M1>;<br>
+
static_assert(std::is_same<T::mutex_type,
M1>::value, "");<br>
+ }<br>
+ {<br>
+ using M1 = std::mutex;<br>
+ using M2 = std::recursive_mutex;<br>
+ using T = std::lock_guard<M1, M2>;<br>
+ static_assert(!has_mutex_type<T>(),
"");<br>
+ }<br>
+ {<br>
+ using M1 = std::mutex;<br>
+ using M2 = std::recursive_mutex;<br>
+ using T = std::lock_guard<M1, M1,
M2>;<br>
+ static_assert(!has_mutex_type<T>(),
"");<br>
+ }<br>
+ {<br>
+ using M1 = std::mutex;<br>
+ using T = std::lock_guard<M1, M1>;<br>
+ static_assert(!has_mutex_type<T>(),
"");<br>
+ }<br>
+ {<br>
+ using M1 = std::recursive_mutex;<br>
+ using T = std::lock_guard<M1, M1,
M1>;<br>
+ static_assert(!has_mutex_type<T>(),
"");<br>
+ }<br>
+}<br>
<br>
Modified: libcxx/trunk/www/cxx1z_status.html<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/cxx1z_status.html?rev=272634&r1=272633&r2=272634&view=diff"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/cxx1z_status.html?rev=272634&r1=272633&r2=272634&view=diff</a><br>
==============================================================================<br>
--- libcxx/trunk/www/cxx1z_status.html (original)<br>
+++ libcxx/trunk/www/cxx1z_status.html Mon Jun 13
22:48:09 2016<br>
@@ -74,7 +74,7 @@<br>
<tr><td><a href="<a
moz-do-not-send="true"
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0006R0.html"
rel="noreferrer" target="_blank"><a class="moz-txt-link-freetext" 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</a></a>">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><br>
<tr><td><a href="<a
moz-do-not-send="true"
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0092R1.html"
rel="noreferrer" target="_blank"><a class="moz-txt-link-freetext" 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</a></a>">P0092R1</a></td><td>LWG</td><td>Polishing
<chrono></td><td>Kona</td><td>Complete</td><td>3.8</td></tr><br>
<tr><td><a href="<a
moz-do-not-send="true"
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0007R1.html"
rel="noreferrer" target="_blank"><a class="moz-txt-link-freetext" 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</a></a>">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><br>
- <tr><td><a href="<a
moz-do-not-send="true"
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0156R0.htm"
rel="noreferrer" target="_blank"><a class="moz-txt-link-freetext" 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</a></a>"
>P0156R0</a></td><td>LWG</td><td>Variadic
lock_guard(rev
3).</td><td>Kona</td><td></td><td></td></tr><br>
+ <tr><td><a href="<a
moz-do-not-send="true"
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0156r0.html"
rel="noreferrer" target="_blank"><a class="moz-txt-link-freetext" 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</a></a>"
>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><br>
<tr><td><a href="<a
moz-do-not-send="true"
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0074R0.html"
rel="noreferrer" target="_blank"><a class="moz-txt-link-freetext" 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</a></a>">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><br>
<tr><td><a href="<a
moz-do-not-send="true"
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/P0013R1.html"
rel="noreferrer" target="_blank"><a class="moz-txt-link-freetext" 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</a></a>">P0013R1</a></td><td>LWG</td><td>Logical
type traits rev
2</td><td>Kona</td><td>Complete</td><td>3.8</td></tr><br>
<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr><br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a moz-do-not-send="true"
href="mailto:cfe-commits@lists.llvm.org"
target="_blank">cfe-commits@lists.llvm.org</a><br>
<a moz-do-not-send="true"
href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits"
rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote>
</div>
<br>
</div>
</div>
</div>
</blockquote>
</div>
<br>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
cfe-commits mailing list
<a class="moz-txt-link-abbreviated" href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a>
</pre>
</blockquote>
<br>
<pre class="moz-signature" cols="72">--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
</pre>
</body>
</html>