From 86dd28a5471480cd7a8cb5ad4801599ac0a0ac20 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 13 Aug 2019 11:12:28 +0000 Subject: [PATCH] [libc++] Use [[nodiscard]] for lock_guard, as an extension Summary: D64914 added support for applying [[nodiscard]] to constructors. This commit uses that capability to flag incorrect uses of std::lock_guard where one forgets to actually create a variable for the lock_guard. rdar://45790820 Reviewers: mclow.lists, EricWF Subscribers: christof, jkorous, dexonsmith, libcxx-commits, Quuxplusone, lebedev.ri Tags: #libc Differential Revision: https://reviews.llvm.org/D65900 llvm-svn: 368664 --- libcxx/docs/UsingLibcxx.rst | 1 + libcxx/include/__mutex_base | 5 +-- .../diagnostics/nodiscard_extensions.fail.cpp | 2 +- .../thread.lock.guard/nodiscard.fail.cpp | 34 +++++++++++++++++++ 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 libcxx/test/libcxx/thread/thread.lock/thread.lock.guard/nodiscard.fail.cpp diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst index 56c98af55866..05721bf271a8 100644 --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -345,3 +345,4 @@ which no dialect declares as such (See the second form described above). * ``search`` * ``unique`` * ``upper_bound`` +* ``lock_guard``'s constructors diff --git a/libcxx/include/__mutex_base b/libcxx/include/__mutex_base index f828beaf780d..a85ded8341e0 100644 --- a/libcxx/include/__mutex_base +++ b/libcxx/include/__mutex_base @@ -94,10 +94,11 @@ private: mutex_type& __m_; public: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m)) : __m_(__m) {__m_.lock();} - _LIBCPP_INLINE_VISIBILITY + + _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m)) : __m_(__m) {} _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/test/libcxx/diagnostics/nodiscard_extensions.fail.cpp b/libcxx/test/libcxx/diagnostics/nodiscard_extensions.fail.cpp index 10582b9378ba..43cc080e2e47 100644 --- a/libcxx/test/libcxx/diagnostics/nodiscard_extensions.fail.cpp +++ b/libcxx/test/libcxx/diagnostics/nodiscard_extensions.fail.cpp @@ -16,7 +16,7 @@ // guides from existing ctors, needed by default_searcher() below. // UNSUPPORTED: apple-clang-9 -// Test that entities declared [[nodiscard]] as at extension by libc++, are +// Test that entities declared [[nodiscard]] as an extension by libc++, are // only actually declared such when _LIBCPP_ENABLE_NODISCARD is specified. // All entities to which libc++ applies [[nodiscard]] as an extension should diff --git a/libcxx/test/libcxx/thread/thread.lock/thread.lock.guard/nodiscard.fail.cpp b/libcxx/test/libcxx/thread/thread.lock/thread.lock.guard/nodiscard.fail.cpp new file mode 100644 index 000000000000..bac255cca0c6 --- /dev/null +++ b/libcxx/test/libcxx/thread/thread.lock/thread.lock.guard/nodiscard.fail.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: libcpp-has-no-threads + +// [[nodiscard]] on constructors isn't supported by all compilers +// UNSUPPORTED: clang-6, clang-6, clang-8, clang-9 +// UNSUPPORTED: apple-clang-9, apple-clang-10, apple-clang-11 + +// + +// template class lock_guard; + +// [[nodiscard]] explicit lock_guard(mutex_type& m); +// [[nodiscard]] lock_guard(mutex_type& m, adopt_lock_t); + +// Test that we properly apply [[nodiscard]] to lock_guard's constructors, +// which is a libc++ extension. + +// MODULES_DEFINES: _LIBCPP_ENABLE_NODISCARD +#define _LIBCPP_ENABLE_NODISCARD +#include + +int main(int, char**) { + std::mutex m; + std::lock_guard{m}; // expected-error{{ignoring temporary created by a constructor declared with 'nodiscard' attribute}} + std::lock_guard{m, std::adopt_lock}; // expected-error{{ignoring temporary created by a constructor declared with 'nodiscard' attribute}} + return 0; +}