diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -345,3 +345,4 @@ * ``search`` * ``unique`` * ``upper_bound`` +* ``lock_guard``'s constructors diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1010,6 +1010,19 @@ # define _LIBCPP_NODISCARD_AFTER_CXX17 #endif +#if __has_cpp_attribute(nodiscard) >= 201907L + // Attribute to use to mark a constructor as [[nodiscard]] when the + // Standard specifies the constructor as [[nodiscard]] +# define _LIBCPP_NODISCARD_CTOR _LIBCPP_NODISCARD + + // Attribute to use to mark a constructor as [[nodiscard]] as a + // libc++ extension. +# define _LIBCPP_NODISCARD_CTOR_EXT _LIBCPP_NODISCARD_EXT +#else +# define _LIBCPP_NODISCARD_CTOR // compiler doesn't support P1771 +# define _LIBCPP_NODISCARD_CTOR_EXT // compiler doesn't support P1771 +#endif + #if _LIBCPP_STD_VER > 14 && defined(__cpp_inline_variables) && (__cpp_inline_variables >= 201606L) # define _LIBCPP_INLINE_VAR inline #else diff --git a/libcxx/include/__mutex_base b/libcxx/include/__mutex_base --- a/libcxx/include/__mutex_base +++ b/libcxx/include/__mutex_base @@ -94,10 +94,11 @@ mutex_type& __m_; public: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NODISCARD_CTOR_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_CTOR_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 --- 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 --- /dev/null +++ b/libcxx/test/libcxx/thread/thread.lock/thread.lock.guard/nodiscard.fail.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// 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; +}