Index: docs/UsingLibcxx.rst =================================================================== --- docs/UsingLibcxx.rst +++ docs/UsingLibcxx.rst @@ -149,3 +149,28 @@ This macro is used to enable -Wthread-safety annotations on libc++'s ``std::mutex`` and ``std::lock_guard``. By default these annotations are disabled and must be manually enabled by the user. + +**_LIBCPP_NO_DISCARD** + This macro is used to annotate various libc++ functions as having a + non-discardable return value. This macro is enabled by default. + + **Overriding**: To fully disable libc++'s no-discard attribute users can + define `_LIBCPP_DISABLE_NO_DISCARD` before including any headers. It's also + possible to disable groups of no-discard checks by defining one of the + macros below: + + * **_LIBCPP_DISABLE_NO_DISCARD_UNIQUE_PTR_RELEASE**: Disables no-discard on + ``std::unique_ptr::release()``. + + * **_LIBCPP_DISABLE_NO_DISCARD_SMART_PTR_OBSERVERS**: Disables no-discard + on non-modifying smart pointer operations such as ``get()`` or + ``operator*()``. + + * **_LIBCPP_DISABLE_NO_DISCARD_CONTAINER_OBSERVERS**: Disables + no-discard on non-modifying container operations such as the ``size()``, + ``empty()``, and ``capacity()`` methods of ``std::vector`` or + ``std::string``. + + * **_LIBCPP_DISABLE_NO_DISCARD_TRY_LOCK**: Disables no-discard on the + ``try_lock()``, ``try_lock_for()``, and ``try_lock_until()`` + members of lockable types. Index: include/__config =================================================================== --- include/__config +++ include/__config @@ -900,6 +900,21 @@ #define _LIBCPP_SAFE_STATIC #endif +#ifndef _LIBCPP_NO_DISCARD +# if !defined(_LIBCPP_DISABLE_NO_DISCARD) && \ + (__has_attribute(warn_unused_result) || _GNUC_VER > 408) +# define _LIBCPP_NO_DISCARD __attribute__((__warn_unused_result__)) +# else +# define _LIBCPP_NO_DISCARD +# endif +#endif // !defined(_LIBCPP_NO_DISCARD) + +#ifndef _LIBCPP_DISABLE_NO_DISCARD_CONTAINER_OBSERVERS +# define _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_NO_DISCARD +#else +# define _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS +#endif + #if !__has_builtin(__builtin_addressof) && _GNUC_VER < 700 #define _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF #endif Index: include/__hash_table =================================================================== --- include/__hash_table +++ include/__hash_table @@ -1608,7 +1608,7 @@ { __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__value_)); __node_insert_multi(__h.get()); - __h.release(); + (void)__h.release(); } } } @@ -2022,7 +2022,7 @@ __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); pair __r = __node_insert_unique(__h.get()); if (__r.second) - __h.release(); + (void)__h.release(); return __r; } @@ -2033,7 +2033,7 @@ { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); iterator __r = __node_insert_multi(__h.get()); - __h.release(); + (void)__h.release(); return __r; } @@ -2050,7 +2050,7 @@ #endif __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); iterator __r = __node_insert_multi(__p, __h.get()); - __h.release(); + (void)__h.release(); return __r; } @@ -2062,7 +2062,7 @@ { __node_holder __h = __construct_node(__x); iterator __r = __node_insert_multi(__h.get()); - __h.release(); + (void)__h.release(); return __r; } @@ -2078,7 +2078,7 @@ #endif __node_holder __h = __construct_node(__x); iterator __r = __node_insert_multi(__p, __h.get()); - __h.release(); + (void)__h.release(); return __r; } Index: include/__mutex_base =================================================================== --- include/__mutex_base +++ include/__mutex_base @@ -32,6 +32,12 @@ # endif #endif // _LIBCPP_THREAD_SAFETY_ANNOTATION +#ifndef _LIBCPP_DISABLE_NO_DISCARD_TRY_LOCK +# define _LIBCPP_NO_DISCARD_TRY_LOCK _LIBCPP_NO_DISCARD +#else +# define _LIBCPP_NO_DISCARD_TRY_LOCK +#endif + class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex { #ifndef _LIBCPP_HAS_NO_CONSTEXPR @@ -55,6 +61,7 @@ public: void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true)); void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()); @@ -182,11 +189,13 @@ #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES void lock(); - bool try_lock(); + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock(); template + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock_for(const chrono::duration<_Rep, _Period>& __d); template + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); void unlock(); Index: include/algorithm =================================================================== --- include/algorithm +++ include/algorithm @@ -3931,7 +3931,7 @@ __d.__incr((value_type*)0); } } - __h.release(); + (void)__h.release(); } } @@ -4661,14 +4661,14 @@ { for (; __first2 != __last2; ++__first2, ++__result, __d.__incr((value_type*)0)) ::new (__result) value_type(_VSTD::move(*__first2)); - __h.release(); + (void)__h.release(); return; } if (__first2 == __last2) { for (; __first1 != __last1; ++__first1, ++__result, __d.__incr((value_type*)0)) ::new (__result) value_type(_VSTD::move(*__first1)); - __h.release(); + (void)__h.release(); return; } if (__comp(*__first2, *__first1)) @@ -4752,7 +4752,7 @@ ++__first2; ::new(__first2) value_type(_VSTD::move(*__last1)); } - __h2.release(); + (void)__h2.release(); return; } if (__len <= 8) Index: include/deque =================================================================== --- include/deque +++ include/deque @@ -2317,7 +2317,7 @@ __alloc_traits::allocate(__a, __base::__block_size), _Dp(__a, __base::__block_size)); __buf.push_back(__hold.get()); - __hold.release(); + (void)__hold.release(); for (typename __base::__map_pointer __i = __base::__map_.begin(); __i != __base::__map_.end(); ++__i) @@ -2460,7 +2460,7 @@ __alloc_traits::allocate(__a, __base::__block_size), _Dp(__a, __base::__block_size)); __buf.push_back(__hold.get()); - __hold.release(); + (void)__hold.release(); for (typename __base::__map_pointer __i = __base::__map_.end(); __i != __base::__map_.begin();) Index: include/ext/hash_map =================================================================== --- include/ext/hash_map +++ include/ext/hash_map @@ -693,7 +693,7 @@ return __i->second; __node_holder __h = __construct_node(__k); pair __r = __table_.__node_insert_unique(__h.get()); - __h.release(); + (void)__h.release(); return __r.first->second; } Index: include/forward_list =================================================================== --- include/forward_list +++ include/forward_list @@ -730,10 +730,10 @@ const_iterator cbefore_begin() const _NOEXCEPT {return const_iterator(base::__before_begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return base::__before_begin()->__next_ == nullptr;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return numeric_limits::max();} Index: include/list =================================================================== --- include/list +++ include/list @@ -898,11 +898,11 @@ _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return base::__sz();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return base::empty();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return numeric_limits::max();} @@ -1426,7 +1426,7 @@ #else __r = iterator(__hold->__as_link()); #endif - __hold.release(); + (void)__hold.release(); iterator __e = __r; #ifndef _LIBCPP_NO_EXCEPTIONS try @@ -1438,7 +1438,7 @@ __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); __e.__ptr_->__next_ = __hold->__as_link(); __hold->__prev_ = __e.__ptr_; - __hold.release(); + (void)__hold.release(); } #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -1494,7 +1494,7 @@ #else __r = iterator(__hold.get()->__as_link()); #endif - __hold.release(); + (void)__hold.release(); iterator __e = __r; #ifndef _LIBCPP_NO_EXCEPTIONS try @@ -1506,7 +1506,7 @@ __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f); __e.__ptr_->__next_ = __hold.get()->__as_link(); __hold->__prev_ = __e.__ptr_; - __hold.release(); + (void)__hold.release(); } #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -1545,7 +1545,7 @@ __link_pointer __nl = __hold->__as_link(); __link_nodes_at_front(__nl, __nl); ++base::__sz(); - __hold.release(); + (void)__hold.release(); } template @@ -1558,7 +1558,7 @@ __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); __link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link()); ++base::__sz(); - __hold.release(); + (void)__hold.release(); } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -1573,7 +1573,7 @@ __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link()); ++base::__sz(); - __hold.release(); + (void)__hold.release(); } template @@ -1586,7 +1586,7 @@ __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); __link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link()); ++base::__sz(); - __hold.release(); + (void)__hold.release(); } #ifndef _LIBCPP_HAS_NO_VARIADICS @@ -1638,7 +1638,7 @@ __link_pointer __nl = __hold.get()->__as_link(); __link_nodes(__p.__ptr_, __nl, __nl); ++base::__sz(); - __hold.release(); + (void)__hold.release(); #if _LIBCPP_DEBUG_LEVEL >= 2 return iterator(__nl, this); #else @@ -1665,7 +1665,7 @@ __link_pointer __nl = __hold->__as_link(); __link_nodes(__p.__ptr_, __nl, __nl); ++base::__sz(); - __hold.release(); + (void)__hold.release(); #if _LIBCPP_DEBUG_LEVEL >= 2 return iterator(__nl, this); #else @@ -1851,7 +1851,7 @@ __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_)); __e.__ptr_->__next_ = __hold.get()->__as_link(); __hold->__prev_ = __e.__ptr_; - __hold.release(); + (void)__hold.release(); } #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -1911,7 +1911,7 @@ __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); __e.__ptr_->__next_ = __hold.get()->__as_link(); __hold->__prev_ = __e.__ptr_; - __hold.release(); + (void)__hold.release(); } #ifndef _LIBCPP_NO_EXCEPTIONS } Index: include/locale =================================================================== --- include/locale +++ include/locale @@ -2767,7 +2767,7 @@ if (__t == 0) __throw_bad_alloc(); if (__owns) - __b.release(); + (void)__b.release(); __b = unique_ptr<_Tp, void(*)(void*)>(__t, free); __new_cap /= sizeof(_Tp); __n = __b.get() + __n_off; Index: include/map =================================================================== --- include/map +++ include/map @@ -1018,11 +1018,11 @@ _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const _NOEXCEPT {return rend();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __tree_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return __tree_.size();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return __tree_.max_size();} mapped_type& operator[](const key_type& __k); @@ -1744,11 +1744,11 @@ _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const _NOEXCEPT {return rend();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __tree_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return __tree_.size();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return __tree_.max_size();} _LIBCPP_INLINE_VISIBILITY Index: include/memory =================================================================== --- include/memory +++ include/memory @@ -649,6 +649,12 @@ #pragma GCC system_header #endif +#ifndef _LIBCPP_DISABLE_NO_DISCARD_SMART_PTR_OBSERVERS +# define _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_NO_DISCARD +#else +# define _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS +#endif + _LIBCPP_BEGIN_NAMESPACE_STD template @@ -2756,18 +2762,24 @@ return *this; } - _LIBCPP_INLINE_VISIBILITY typename add_lvalue_reference<_Tp>::type operator*() const + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY + typename add_lvalue_reference<_Tp>::type operator*() const {return *__ptr_.first();} - _LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT {return __ptr_.first();} - _LIBCPP_INLINE_VISIBILITY pointer get() const _NOEXCEPT {return __ptr_.first();} - _LIBCPP_INLINE_VISIBILITY _Dp_reference get_deleter() _NOEXCEPT + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY + pointer operator->() const _NOEXCEPT {return __ptr_.first();} + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY + pointer get() const _NOEXCEPT {return __ptr_.first();} + _LIBCPP_INLINE_VISIBILITY _Dp_reference get_deleter() _NOEXCEPT {return __ptr_.second();} _LIBCPP_INLINE_VISIBILITY _Dp_const_reference get_deleter() const _NOEXCEPT {return __ptr_.second();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return __ptr_.first() != nullptr;} +#ifndef _LIBCPP_DISABLE_NO_DISCARD_UNIQUE_PTR_RELEASE + _LIBCPP_NO_DISCARD +#endif _LIBCPP_INLINE_VISIBILITY pointer release() _NOEXCEPT { pointer __t = __ptr_.first(); @@ -2948,17 +2960,22 @@ return *this; } - _LIBCPP_INLINE_VISIBILITY typename add_lvalue_reference<_Tp>::type operator[](size_t __i) const + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY + typename add_lvalue_reference<_Tp>::type operator[](size_t __i) const {return __ptr_.first()[__i];} - _LIBCPP_INLINE_VISIBILITY pointer get() const _NOEXCEPT {return __ptr_.first();} + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY + pointer get() const _NOEXCEPT {return __ptr_.first();} _LIBCPP_INLINE_VISIBILITY _Dp_reference get_deleter() _NOEXCEPT {return __ptr_.second();} _LIBCPP_INLINE_VISIBILITY _Dp_const_reference get_deleter() const _NOEXCEPT {return __ptr_.second();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return __ptr_.first() != nullptr;} +#ifndef _LIBCPP_DISABLE_NO_DISCARD_UNIQUE_PTR_RELEASE + _LIBCPP_NO_DISCARD +#endif _LIBCPP_INLINE_VISIBILITY pointer release() _NOEXCEPT { pointer __t = __ptr_.first(); @@ -4022,7 +4039,7 @@ virtual void __on_zero_shared() _NOEXCEPT; virtual void __on_zero_shared_weak() _NOEXCEPT; public: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD _LIBCPP_INLINE_VISIBILITY _Tp* get() _NOEXCEPT {return &__data_.second();} }; @@ -4229,18 +4246,18 @@ _LIBCPP_INLINE_VISIBILITY reset(_Yp* __p, _Dp __d, _Alloc __a); - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY element_type* get() const _NOEXCEPT {return __ptr_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY typename add_lvalue_reference::type operator*() const _NOEXCEPT {return *__ptr_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY element_type* operator->() const _NOEXCEPT {return __ptr_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool unique() const _NOEXCEPT {return use_count() == 1;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return get() != 0;} template _LIBCPP_INLINE_VISIBILITY @@ -4355,7 +4372,7 @@ unique_ptr<_Yp> __hold(__p); typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk; __cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), allocator<_Yp>()); - __hold.release(); + (void)__hold.release(); __enable_weak_this(__p, __p); } @@ -4562,7 +4579,7 @@ __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), allocator<_Yp>()); __enable_weak_this(__r.get(), __r.get()); } - __r.release(); + (void)__r.release(); } template @@ -5327,10 +5344,10 @@ _LIBCPP_INLINE_VISIBILITY void reset() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_SMART_PTR_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool expired() const _NOEXCEPT {return __cntrl_ == 0 || __cntrl_->use_count() == 0;} shared_ptr<_Tp> lock() const _NOEXCEPT; Index: include/mutex =================================================================== --- include/mutex +++ include/mutex @@ -218,7 +218,7 @@ public: void lock(); - bool try_lock() _NOEXCEPT; + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock() _NOEXCEPT; void unlock() _NOEXCEPT; typedef __libcpp_mutex_t* native_handle_type; @@ -241,12 +241,13 @@ public: void lock(); - bool try_lock() _NOEXCEPT; + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock() _NOEXCEPT; template - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_TRY_LOCK _LIBCPP_INLINE_VISIBILITY bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {return try_lock_until(chrono::steady_clock::now() + __d);} template + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); void unlock() _NOEXCEPT; }; @@ -284,12 +285,13 @@ public: void lock(); - bool try_lock() _NOEXCEPT; + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock() _NOEXCEPT; template - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_TRY_LOCK _LIBCPP_INLINE_VISIBILITY bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {return try_lock_until(chrono::steady_clock::now() + __d);} template + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); void unlock() _NOEXCEPT; }; Index: include/regex =================================================================== --- include/regex +++ include/regex @@ -3015,7 +3015,7 @@ { unique_ptr<__node> __h(new __end_state<_CharT>); __start_.reset(new __empty_state<_CharT>(__h.get())); - __h.release(); + (void)__h.release(); __end_ = __start_.get(); } switch (__flags_ & 0x1F0) @@ -4608,7 +4608,7 @@ __s->first(), __e1.get(), __mexp_begin, __mexp_end, __greedy, __min, __max)); __s->first() = nullptr; - __e1.release(); + (void)__e1.release(); __end_->first() = new __repeat_one_loop<_CharT>(__e2.get()); __end_ = __e2->second(); __s->first() = __e2.release(); Index: include/set =================================================================== --- include/set +++ include/set @@ -579,11 +579,11 @@ _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const _NOEXCEPT {return rend();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __tree_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return __tree_.size();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return __tree_.max_size();} // modifiers: @@ -991,11 +991,11 @@ _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const _NOEXCEPT {return rend();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __tree_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return __tree_.size();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return __tree_.max_size();} // modifiers: Index: include/shared_mutex =================================================================== --- include/shared_mutex +++ include/shared_mutex @@ -159,12 +159,12 @@ // Exclusive ownership void lock(); // blocking - bool try_lock(); + _LIBCPP_NO_DISCARD bool try_lock(); void unlock(); // Shared ownership void lock_shared(); // blocking - bool try_lock_shared(); + _LIBCPP_NO_DISCARD bool try_lock_shared(); void unlock_shared(); // typedef implementation-defined native_handle_type; // See 30.2.3 @@ -185,12 +185,14 @@ // Exclusive ownership _LIBCPP_INLINE_VISIBILITY void lock() { return __base.lock(); } - _LIBCPP_INLINE_VISIBILITY bool try_lock() { return __base.try_lock(); } + _LIBCPP_NO_DISCARD_TRY_LOCK _LIBCPP_INLINE_VISIBILITY + bool try_lock() { return __base.try_lock(); } _LIBCPP_INLINE_VISIBILITY void unlock() { return __base.unlock(); } // Shared ownership _LIBCPP_INLINE_VISIBILITY void lock_shared() { return __base.lock_shared(); } - _LIBCPP_INLINE_VISIBILITY bool try_lock_shared() { return __base.try_lock_shared(); } + _LIBCPP_NO_DISCARD_TRY_LOCK _LIBCPP_INLINE_VISIBILITY + bool try_lock_shared() { return __base.try_lock_shared(); } _LIBCPP_INLINE_VISIBILITY void unlock_shared() { return __base.unlock_shared(); } // typedef __shared_mutex_base::native_handle_type native_handle_type; @@ -211,31 +213,31 @@ // Exclusive ownership void lock(); - bool try_lock(); + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock(); template - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_TRY_LOCK _LIBCPP_INLINE_VISIBILITY bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time) { return try_lock_until(chrono::steady_clock::now() + __rel_time); } template - bool + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time); void unlock(); // Shared ownership void lock_shared(); - bool try_lock_shared(); + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock_shared(); template - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_TRY_LOCK _LIBCPP_INLINE_VISIBILITY bool try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time) { return try_lock_shared_until(chrono::steady_clock::now() + __rel_time); } template - bool + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time); void unlock_shared(); }; @@ -391,10 +393,12 @@ } void lock(); - bool try_lock(); + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock(); template + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock_for(const chrono::duration& rel_time); template + _LIBCPP_NO_DISCARD_TRY_LOCK bool try_lock_until(const chrono::time_point& abs_time); void unlock(); Index: include/string =================================================================== --- include/string +++ include/string @@ -879,11 +879,15 @@ const_reverse_iterator crend() const _NOEXCEPT {return rend();} - _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return __is_long() ? __get_long_size() : __get_short_size();} - _LIBCPP_INLINE_VISIBILITY size_type length() const _NOEXCEPT {return size();} - _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY + size_type length() const _NOEXCEPT {return size();} + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT; + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY + size_type capacity() const _NOEXCEPT {return (__is_long() ? __get_long_cap() : static_cast(__min_cap)) - 1;} @@ -895,7 +899,8 @@ void shrink_to_fit() _NOEXCEPT {reserve();} _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return size() == 0;} + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY + bool empty() const _NOEXCEPT {return size() == 0;} _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __pos) _NOEXCEPT; Index: include/string_view =================================================================== --- include/string_view +++ include/string_view @@ -241,17 +241,17 @@ const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } // [string.view.capacity], capacity - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT { return __size; } - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type length() const _NOEXCEPT { return __size; } - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT { return numeric_limits::max(); } - _LIBCPP_CONSTEXPR bool _LIBCPP_INLINE_VISIBILITY - empty() const _NOEXCEPT { return __size == 0; } + _LIBCPP_CONSTEXPR _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY + bool empty() const _NOEXCEPT { return __size == 0; } // [string.view.access], element access _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY Index: include/thread =================================================================== --- include/thread +++ include/thread @@ -362,7 +362,7 @@ __decay_copy(_VSTD::forward<_Args>(__args))...)); int __ec = __libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get()); if (__ec == 0) - __p.release(); + (void)__p.release(); else __throw_system_error(__ec, "thread constructor failed"); } @@ -397,7 +397,7 @@ _PairPtr __pp(new _InvokePair(__f)); int __ec = __libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get()); if (__ec == 0) - __pp.release(); + (void)__pp.release(); else __throw_system_error(__ec, "thread constructor failed"); } Index: include/unordered_map =================================================================== --- include/unordered_map +++ include/unordered_map @@ -893,11 +893,11 @@ allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__table_.__node_alloc());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __table_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return __table_.size();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return __table_.max_size();} _LIBCPP_INLINE_VISIBILITY @@ -1647,11 +1647,11 @@ allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__table_.__node_alloc());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __table_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return __table_.size();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return __table_.max_size();} _LIBCPP_INLINE_VISIBILITY Index: include/unordered_set =================================================================== --- include/unordered_set +++ include/unordered_set @@ -454,11 +454,11 @@ allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__table_.__node_alloc());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __table_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return __table_.size();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return __table_.max_size();} _LIBCPP_INLINE_VISIBILITY @@ -992,11 +992,11 @@ allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__table_.__node_alloc());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __table_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return __table_.size();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return __table_.max_size();} _LIBCPP_INLINE_VISIBILITY Index: include/vector =================================================================== --- include/vector +++ include/vector @@ -627,16 +627,16 @@ const_reverse_iterator crend() const _NOEXCEPT {return rend();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return static_cast(this->__end_ - this->__begin_);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT {return __base::capacity();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return this->__begin_ == this->__end_;} - size_type max_size() const _NOEXCEPT; + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS size_type max_size() const _NOEXCEPT; void reserve(size_type __n); void shrink_to_fit() _NOEXCEPT; @@ -2242,14 +2242,14 @@ _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const _NOEXCEPT {return allocator_type(this->__alloc());} - size_type max_size() const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS size_type max_size() const _NOEXCEPT; + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT {return __internal_cap_to_external(__cap());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return __size_;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NO_DISCARD_CONTAINER_OBSERVERS _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __size_ == 0;} void reserve(size_type __n); Index: test/libcxx/containers/no-discard-disable.fail.cpp =================================================================== --- /dev/null +++ test/libcxx/containers/no-discard-disable.fail.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-diagnostics + +// test the generated [[no_discard]] warnings + +#define _LIBCPP_DISABLE_NO_DISCARD_CONTAINER_OBSERVERS +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Note: -Wunused-result is not emitted from within function templates so +// we instead use a macro to avoid duplication. +#define TEST_WARNING4(...) \ + do { __VA_ARGS__ C; C.empty(); C.size(); C.capacity(); C.max_size(); } while (false) + +#define TEST_WARNING3(...) \ + do { __VA_ARGS__ C; C.empty(); C.size(); C.max_size(); } while (false) + +int main() { + // expected-no-diagnostics + // std::vector + { + TEST_WARNING4(std::vector); + TEST_WARNING4(std::vector); + } + // std::string + { + TEST_WARNING4(std::string); + std::string s; + s.length(); + } + { + TEST_WARNING3(std::string_view); + std::string_view s; + s.length(); + } + { + TEST_WARNING3(std::list); + } + { + std::forward_list C; + C.empty(); + C.max_size(); + } + { + TEST_WARNING3(std::set); + TEST_WARNING3(std::multiset); + } + { + TEST_WARNING3(std::map); + TEST_WARNING3(std::multimap); + } + { + TEST_WARNING3(std::unordered_set); + TEST_WARNING3(std::unordered_multiset); + } + { + TEST_WARNING3(std::unordered_map); + TEST_WARNING3(std::unordered_multimap); + } +} Index: test/libcxx/containers/no-discard.fail.cpp =================================================================== --- /dev/null +++ test/libcxx/containers/no-discard.fail.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-diagnostics + +// test the generated [[no_discard]] warnings + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Note: -Wunused-result is not emitted from within function templates so +// we instead use a macro to avoid duplication. +#define TEST_WARNING4(...) \ + do { __VA_ARGS__ C; C.empty(); C.size(); C.capacity(); C.max_size(); } while (false) + +#define TEST_WARNING3(...) \ + do { __VA_ARGS__ C; C.empty(); C.size(); C.max_size(); } while (false) + +int main() { + // std::vector + { + TEST_WARNING4(std::vector); // expected-warning 4 {{ignoring return value}} + TEST_WARNING4(std::vector); // expected-warning 4 {{ignoring return value}} + } + // std::string + { + TEST_WARNING4(std::string); // expected-warning 4 {{ignoring return value}} + std::string s; + s.length(); // expected-warning {{ignoring return value}} + } + { + TEST_WARNING3(std::string_view); // expected-warning 3 {{ignoring return value}} + std::string_view s; + s.length(); // expected-warning {{ignoring return value}} + } + { + TEST_WARNING3(std::list); // expected-warning 3 {{ignoring return value}} + } + { + std::forward_list C; + C.empty(); // expected-warning {{ignoring return value}} + C.max_size(); // expected-warning {{ignoring return value}} + } + { + TEST_WARNING3(std::set); // expected-warning 3 {{ignoring return value}} + TEST_WARNING3(std::multiset); // expected-warning 3 {{ignoring return value}} + } + { + TEST_WARNING3(std::map); // expected-warning 3 {{ignoring return value}} + TEST_WARNING3(std::multimap); // expected-warning 3 {{ignoring return value}} + } + { + TEST_WARNING3(std::unordered_set); // expected-warning 3 {{ignoring return value}} + TEST_WARNING3(std::unordered_multiset); // expected-warning 3 {{ignoring return value}} + } + { + TEST_WARNING3(std::unordered_map); // expected-warning 3 {{ignoring return value}} + TEST_WARNING3(std::unordered_multimap); // expected-warning 3 {{ignoring return value}} + } +} Index: test/libcxx/test/config.py =================================================================== --- test/libcxx/test/config.py +++ test/libcxx/test/config.py @@ -249,6 +249,8 @@ ['-Xclang', '-verify-ignore-unexpected']) self.lit_config.note( "inferred use_clang_verify as: %r" % self.use_clang_verify) + if self.use_clang_verify: + self.config.available_features.add('verify-diagnostics') def configure_use_thread_safety(self): '''If set, run clang with -verify on failing tests.''' Index: test/libcxx/thread/thread.mutex/try_lock_no_discard.fail.cpp =================================================================== --- /dev/null +++ test/libcxx/thread/thread.mutex/try_lock_no_discard.fail.cpp @@ -0,0 +1,103 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// REQUIRES: verify-diagnostics + +// test the generated [[no_discard]] warnings + +#include +#include + +#include "test_macros.h" + +int main() { + { + std::mutex m; + m.try_lock(); // expected-warning {{ignoring return value}} + m.unlock(); + } + { + std::recursive_mutex m; + m.try_lock(); // expected-warning {{ignoring return value}} + m.unlock(); + } + { + std::timed_mutex m; + m.try_lock(); // expected-warning {{ignoring return value}} + m.unlock(); + m.try_lock_for(std::chrono::seconds(1)); // expected-warning {{ignoring return value}} + m.unlock(); + m.try_lock_until(std::chrono::steady_clock::now() + std::chrono::seconds(1)); // expected-warning {{ignoring return value}} + m.unlock(); + } + { + std::recursive_timed_mutex m; + m.try_lock(); // expected-warning {{ignoring return value}} + m.unlock(); + m.try_lock_for(std::chrono::seconds(1)); // expected-warning {{ignoring return value}} + m.unlock(); + m.try_lock_until(std::chrono::steady_clock::now() + std::chrono::seconds(1)); // expected-warning {{ignoring return value}} + m.unlock(); + } + { + std::mutex m; + std::unique_lock lk(m); + lk.unlock(); + lk.try_lock(); // expected-warning {{ignoring return value}} + } + { + std::timed_mutex m; + std::unique_lock lk(m); + lk.unlock(); + lk.try_lock(); // expected-warning {{ignoring return value}} + lk.unlock(); + lk.try_lock_for(std::chrono::seconds(1)); // expected-warning {{ignoring return value}} + lk.unlock(); + lk.try_lock_until(std::chrono::steady_clock::now() + std::chrono::seconds(1)); // expected-warning {{ignoring return value}} + lk.unlock(); + } +#if TEST_STD_VER > 11 + { + std::shared_timed_mutex m; + m.try_lock(); // expected-warning {{ignoring return value}} + m.unlock(); + m.try_lock_for(std::chrono::seconds(1)); // expected-warning {{ignoring return value}} + m.unlock(); + m.try_lock_until(std::chrono::steady_clock::now() + std::chrono::seconds(1)); // expected-warning {{ignoring return value}} + m.unlock(); + m.try_lock_shared(); // expected-warning {{ignoring return value}} + m.unlock(); + m.try_lock_shared_for(std::chrono::seconds(1)); // expected-warning {{ignoring return value}} + m.unlock(); + m.try_lock_shared_until(std::chrono::steady_clock::now() + std::chrono::seconds(1)); // expected-warning {{ignoring return value}} + m.unlock(); + } + { + std::shared_timed_mutex m; + std::shared_lock lk(m); + lk.unlock(); + lk.try_lock(); // expected-warning {{ignoring return value}} + lk.unlock(); + lk.try_lock_for(std::chrono::seconds(1)); // expected-warning {{ignoring return value}} + lk.unlock(); + lk.try_lock_until(std::chrono::steady_clock::now() + std::chrono::seconds(1)); // expected-warning {{ignoring return value}} + lk.unlock(); + } +#endif +#if TEST_STD_VER > 14 + { + std::shared_mutex m; + m.try_lock(); // expected-warning {{ignoring return value}} + m.unlock(); + m.try_lock_shared(); // expected-warning {{ignoring return value}} + m.unlock(); + }; +#endif +} Index: test/libcxx/thread/thread.mutex/try_lock_no_discard_disabled.fail.cpp =================================================================== --- /dev/null +++ test/libcxx/thread/thread.mutex/try_lock_no_discard_disabled.fail.cpp @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// REQUIRES: verify-diagnostics + +// test the generated [[no_discard]] warnings + +#define _LIBCPP_DISABLE_NO_DISCARD_TRY_LOCK +#include +#include + +#include "test_macros.h" + +int main() { + // expected-no-diagnostics + { + std::mutex m; + m.try_lock(); + m.unlock(); + } + { + std::recursive_mutex m; + m.try_lock(); + m.unlock(); + } + { + std::timed_mutex m; + m.try_lock(); + m.unlock(); + m.try_lock_for(std::chrono::seconds(1)); + m.unlock(); + m.try_lock_until(std::chrono::steady_clock::now() + std::chrono::seconds(1)); + m.unlock(); + } + { + std::recursive_timed_mutex m; + m.try_lock(); + m.unlock(); + m.try_lock_for(std::chrono::seconds(1)); + m.unlock(); + m.try_lock_until(std::chrono::steady_clock::now() + std::chrono::seconds(1)); + m.unlock(); + } + { + std::mutex m; + std::unique_lock lk(m); + lk.unlock(); + lk.try_lock(); + } + { + std::timed_mutex m; + std::unique_lock lk(m); + lk.unlock(); + lk.try_lock(); + lk.unlock(); + lk.try_lock_for(std::chrono::seconds(1)); + lk.unlock(); + lk.try_lock_until(std::chrono::steady_clock::now() + std::chrono::seconds(1)); + lk.unlock(); + } +#if TEST_STD_VER > 11 + { + std::shared_timed_mutex m; + m.try_lock(); + m.unlock(); + m.try_lock_for(std::chrono::seconds(1)); + m.unlock(); + m.try_lock_until(std::chrono::steady_clock::now() + std::chrono::seconds(1)); + m.unlock(); + m.try_lock_shared(); + m.unlock(); + m.try_lock_shared_for(std::chrono::seconds(1)); + m.unlock(); + m.try_lock_shared_until(std::chrono::steady_clock::now() + std::chrono::seconds(1)); + m.unlock(); + } + { + std::shared_timed_mutex m; + std::shared_lock lk(m); + lk.unlock(); + lk.try_lock(); + lk.unlock(); + lk.try_lock_for(std::chrono::seconds(1)); + lk.unlock(); + lk.try_lock_until(std::chrono::steady_clock::now() + std::chrono::seconds(1)); + lk.unlock(); + } +#endif +#if TEST_STD_VER > 14 + { + std::shared_mutex m; + m.try_lock(); + m.unlock(); + m.try_lock_shared(); + m.unlock(); + }; +#endif +} Index: test/libcxx/utilities/memory/disable_no_discard_smart_ptr_observers.fail.cpp =================================================================== --- /dev/null +++ test/libcxx/utilities/memory/disable_no_discard_smart_ptr_observers.fail.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-diagnostics + +// + +// test the generated [[no_discard]] warnings for shared_ptr, +// weak_ptr, and unique_ptr's observers. + +#define _LIBCPP_DISABLE_NO_DISCARD_SMART_PTR_OBSERVERS +#include +#include + +int main() +{ + // expected-no-diagnostics + // shared_ptr + { + std::shared_ptr p; + p.get(); + *p; + p.operator->(); + p.operator bool(); + p.use_count(); + p.unique(); + } + // weak_ptr + { + std::weak_ptr p; + p.use_count(); + p.expired(); + } + // unique_ptr single + { + std::unique_ptr p; + p.get(); + *p; + p.operator->(); + p.operator bool(); + } + // unique_ptr array + { + std::unique_ptr p; + p.get(); + p[0]; + p.operator bool(); + } +} Index: test/libcxx/utilities/memory/no_discard_smart_ptr_observers.fail.cpp =================================================================== --- /dev/null +++ test/libcxx/utilities/memory/no_discard_smart_ptr_observers.fail.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-diagnostics + +// + +// test the generated [[no_discard]] warnings for shared_ptr, +// weak_ptr, and unique_ptr's observers. + +#include +#include + +int main() +{ + // shared_ptr + { + std::shared_ptr p; + p.get(); // expected-warning {{ignoring return value}} + *p; // expected-warning {{ignoring return value}} + p.operator->(); // expected-warning {{ignoring return value}} + p.operator bool(); // expected-warning {{ignoring return value}} + p.use_count(); // expected-warning {{ignoring return value}} + p.unique(); // expected-warning {{ignoring return value}} + } + // weak_ptr + { + std::weak_ptr p; + p.use_count(); // expected-warning {{ignoring return value}} + p.expired(); // expected-warning {{ignoring return value}} + } + // unique_ptr single + { + std::unique_ptr p; + p.get(); // expected-warning {{ignoring return value}} + *p; // expected-warning {{ignoring return value}} + p.operator->(); // expected-warning {{ignoring return value}} + p.operator bool(); // expected-warning {{ignoring return value}} + } + // unique_ptr array + { + std::unique_ptr p; + p.get(); // expected-warning {{ignoring return value}} + p[0]; // expected-warning {{ignoring return value}} + p.operator bool(); // expected-warning {{ignoring return value}} + } +} Index: test/libcxx/utilities/memory/unique.ptr/disable_no_discard_release.fail.cpp =================================================================== --- /dev/null +++ test/libcxx/utilities/memory/unique.ptr/disable_no_discard_release.fail.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-diagnostics + +// + +// unique_ptr + +// test [[no_discard]] warnings for release + +#define _LIBCPP_DISABLE_NO_DISCARD_UNIQUE_PTR_RELEASE +#include +#include + +int main() +{ + // expected-no-diagnostics + { + std::unique_ptr p; + p.release(); + } + { + std::unique_ptr p; + p.release(); + } +} Index: test/libcxx/utilities/memory/unique.ptr/no_discard_release.fail.cpp =================================================================== --- /dev/null +++ test/libcxx/utilities/memory/unique.ptr/no_discard_release.fail.cpp @@ -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. +// +//===----------------------------------------------------------------------===// + +// REQUIRES: verify-diagnostics + +// + +// unique_ptr + +// test [[no_discard]] warnings for release + +#include +#include + +int main() +{ + { + std::unique_ptr p; + p.release(); // expected-warning {{ignoring return value}} + } + { + std::unique_ptr p; + p.release(); // expected-warning {{ignoring return value}} + } +} Index: test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp =================================================================== --- test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp +++ test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp @@ -44,7 +44,7 @@ #ifndef TEST_HAS_NO_EXCEPTIONS try { - lk.try_lock(); + (void)lk.try_lock(); assert(false); } catch (std::system_error& e) @@ -60,7 +60,7 @@ #ifndef TEST_HAS_NO_EXCEPTIONS try { - lk.try_lock(); + (void)lk.try_lock(); assert(false); } catch (std::system_error& e) Index: test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp =================================================================== --- test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp +++ test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp @@ -49,7 +49,7 @@ #ifndef TEST_HAS_NO_EXCEPTIONS try { - lk.try_lock_for(ms(5)); + (void)lk.try_lock_for(ms(5)); assert(false); } catch (std::system_error& e) @@ -65,7 +65,7 @@ #ifndef TEST_HAS_NO_EXCEPTIONS try { - lk.try_lock_for(ms(5)); + (void)lk.try_lock_for(ms(5)); assert(false); } catch (std::system_error& e) Index: test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp =================================================================== --- test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp +++ test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp @@ -49,7 +49,7 @@ #ifndef TEST_HAS_NO_EXCEPTIONS try { - lk.try_lock_until(Clock::now()); + (void)lk.try_lock_until(Clock::now()); assert(false); } catch (std::system_error& e) @@ -65,7 +65,7 @@ #ifndef TEST_HAS_NO_EXCEPTIONS try { - lk.try_lock_until(Clock::now()); + (void)lk.try_lock_until(Clock::now()); assert(false); } catch (std::system_error& e) Index: test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp =================================================================== --- test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp +++ test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp @@ -43,7 +43,7 @@ #ifndef TEST_HAS_NO_EXCEPTIONS try { - lk.try_lock(); + (void)lk.try_lock(); assert(false); } catch (std::system_error& e) @@ -59,7 +59,7 @@ #ifndef TEST_HAS_NO_EXCEPTIONS try { - lk.try_lock(); + (void)lk.try_lock(); assert(false); } catch (std::system_error& e) Index: test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp =================================================================== --- test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp +++ test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp @@ -48,7 +48,7 @@ #ifndef TEST_HAS_NO_EXCEPTIONS try { - lk.try_lock_for(ms(5)); + (void)lk.try_lock_for(ms(5)); assert(false); } catch (std::system_error& e) @@ -64,7 +64,7 @@ #ifndef TEST_HAS_NO_EXCEPTIONS try { - lk.try_lock_for(ms(5)); + (void)lk.try_lock_for(ms(5)); assert(false); } catch (std::system_error& e) Index: test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp =================================================================== --- test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp +++ test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp @@ -48,7 +48,7 @@ #ifndef TEST_HAS_NO_EXCEPTIONS try { - lk.try_lock_until(Clock::now()); + (void)lk.try_lock_until(Clock::now()); assert(false); } catch (std::system_error& e) @@ -64,7 +64,7 @@ #ifndef TEST_HAS_NO_EXCEPTIONS try { - lk.try_lock_until(Clock::now()); + (void)lk.try_lock_until(Clock::now()); assert(false); } catch (std::system_error& e)