diff mbox series

Implement C++20 feature P0600r1: nodiscard in the library

Message ID eccb5b47-869d-313a-4932-ae65704f31ec@redhat.com
State New
Headers show
Series Implement C++20 feature P0600r1: nodiscard in the library | expand

Commit Message

Ulrich Drepper Jan. 20, 2019, 4:09 p.m. UTC
Since a previous patch introduced the _GLIBCXX_NODISCARD macro it is now
simple to implement the rest of P0600.  The parts specific to C++20 were
already added, this patch adds the attribute to the other functions.

Even though the feature specifies the nodiscard attribute only for C++20
it makes no sense to restrict its use.  Code which provokes the warning
but uses C++17 also has a problem.  I do not propose to go beyond C++17
yet.  Just as for the shared_ptr comparison patch, let's first see how
things go and then we can extend the attribute to previous revisions.

If a code base is compiled with multiple compilers chances are that no
problem will be flagged.  Other library implementations are much more
aggressive with the use of this flag.  In the gcc code base on one test
case was flagged and that code sequence obviously should never appear in
real code (allocate and discard the result).

The test suite shows no additional errors and given that only the
functions mentioned in the feature (allocate, empty, new, async) are
changed I think this is a patch which can be applied to the trunk.  It
can catch real mistakes.

OK?

gcc/testsuite/ChangeLog
2019-02-20  Ulrich Drepper  <drepper@redhat.com>

	Fix after P0600.
	* g++.dg/init/new39.C: Don't just ignore result of new.

libstdc++/ChangeLog
2019-02-20  Ulrich Drepper  <drepper@redhat.com>

	Implement C++20 P0600r1.
	* include/backward/hash_map: Add nodiscard attribute to empty.
	* include/backward/hash_set: Likewise.
	* backward/hashtable.h: Likewise.
	* include/bits/basic_string.h: Likewise.
	* include/bits/forward_list.h: Likewise.
	* include/bits/hashtable.h: Likewise.
	* include/bits/regex.h: Likewise.
	* include/bits/stl_deque.h: Likewise.
	* include/bits/stl_list.h: Likewise.
	* include/bits/stl_map.h: Likewise.
	* include/bits/stl_multimap.h: Likewise.
	* include/bits/stl_multiset.h: Likewise.
	* include/bits/stl_queue.h: Likewise.
	* include/bits/stl_set.h: Likewise.
	* include/bits/stl_stack.h: Likewise.
	* include/bits/stl_tree.h: Likewise.
	* include/bits/stl_vector.h: Likewise.
	* include/bits/unordered_map.h: Likewise.
	* include/bits/unordered_set.h: Likewise.
	* include/debug/array: Likewise.
	* include/experimental/any: Likewise.
	* include/experimental/bits/fs_path.h: Likewise.
	* include/experimental/internet: Likewise.
	* include/experimental/string_view: Likewise.
	* include/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp:
	Likewise.
	* include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp:
	Likewise.
	* include/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp:
	Likewise.
	* include/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp:
	Likewise.
	* include/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp:
	Likewise.
	* include/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp:
	Likewise.
	* include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp:
	Likewise.
	* include/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp:
	Likewise.
	* include/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp:
	Likewise.
	*
include/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp:
	Likewise.
	* include/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp:
	Likewise.
	* include/ext/pb_ds/detail/list_update_map_/lu_map_.hpp:
	Likewise.
	* include/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp:
	Likewise.
	* include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hp:
	Likewise.
	* include/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp:
	Likewise.
	* include/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp:
	Likewise.
	* include/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp:
	Likewise.
	* include/ext/pb_ds/detail/tree_trace_base.hpp: Likewise.
	* include/ext/pb_ds/trie_policy.hpp: Likewise.
	* include/ext/rope: Likewise.
	* include/ext/slist: Likewise.
	* include/ext/vstring.h: Likewise.
	* include/profile/array: Likewise.
	* include/std/array: Likewise.
	* include/tr1/array: Likewise.
	* include/tr1/hashtable.h: Likewise.
	* include/tr1/regex: Likewise.
	* include/tr2/dynamic_bitset: Likewise.
	* include/bits/alloc_traits.h: Add nodiscard attribute to
	allocate.
	* include/experimental/memory_resource: Likewise.
	* include/ext/alloc_traits.h: Likewise.
	* include/ext/array_allocator.h: Likewise.
	* include/ext/bitmap_allocator.h: Likewise.
	* include/ext/debug_allocator.h: Likewise.
	* include/ext/extptr_allocator.h: Likewise.
	* include/ext/mt_allocator.h: Likewise.
	* include/ext/new_allocator.h: Likewise.
	* include/ext/pool_allocator.h: Likewise.
	* include/ext/throw_allocator.h: Likewise.
	* include/std/scoped_allocator: Likewise.
	* libsupc++/eh_alloc.cc: Likewise.
	* include/std/future: Add nodiscard attribute to async.
	* libsupc++/new: Add nodiscard attribute to new.

Comments

Jonathan Wakely Jan. 21, 2019, 11:18 a.m. UTC | #1
On 20/01/19 17:09 +0100, Ulrich Drepper wrote:
>Since a previous patch introduced the _GLIBCXX_NODISCARD macro it is now
>simple to implement the rest of P0600.  The parts specific to C++20 were
>already added, this patch adds the attribute to the other functions.
>
>Even though the feature specifies the nodiscard attribute only for C++20
>it makes no sense to restrict its use.  Code which provokes the warning
>but uses C++17 also has a problem.  I do not propose to go beyond C++17
>yet.  Just as for the shared_ptr comparison patch, let's first see how
>things go and then we can extend the attribute to previous revisions.
>
>If a code base is compiled with multiple compilers chances are that no
>problem will be flagged.  Other library implementations are much more
>aggressive with the use of this flag.  In the gcc code base on one test
>case was flagged and that code sequence obviously should never appear in
>real code (allocate and discard the result).
>
>The test suite shows no additional errors and given that only the
>functions mentioned in the feature (allocate, empty, new, async) are
>changed I think this is a patch which can be applied to the trunk.  It
>can catch real mistakes.
>
>OK?

OK, thanks.
diff mbox series

Patch

diff --git a/gcc/testsuite/g++.dg/init/new39.C b/gcc/testsuite/g++.dg/init/new39.C
index f274ebb7b9d..430701db684 100644
--- a/gcc/testsuite/g++.dg/init/new39.C
+++ b/gcc/testsuite/g++.dg/init/new39.C
@@ -57,7 +57,7 @@  int
 main ()
 {
   try {
-    ::operator new(size_t(-1));
+    (void) ::operator new(size_t(-1));
     abort ();
   } catch (std::bad_alloc &) {
   }
diff --git a/libstdc++-v3/include/backward/hash_map b/libstdc++-v3/include/backward/hash_map
index 9f47970767d..66a5218fc6f 100644
--- a/libstdc++-v3/include/backward/hash_map
+++ b/libstdc++-v3/include/backward/hash_map
@@ -166,7 +166,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const
       { return _M_ht.max_size(); }
       
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const
       { return _M_ht.empty(); }
   
@@ -385,7 +385,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const
       { return _M_ht.max_size(); }
 
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const
       { return _M_ht.empty(); }
 
diff --git a/libstdc++-v3/include/backward/hash_set b/libstdc++-v3/include/backward/hash_set
index 2515cd1dafa..2dc0ed774fa 100644
--- a/libstdc++-v3/include/backward/hash_set
+++ b/libstdc++-v3/include/backward/hash_set
@@ -168,7 +168,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const
       { return _M_ht.max_size(); }
       
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const
       { return _M_ht.empty(); }
       
@@ -369,7 +369,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const
       { return _M_ht.max_size(); }
 
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const
       { return _M_ht.empty(); }
 
diff --git a/libstdc++-v3/include/backward/hashtable.h b/libstdc++-v3/include/backward/hashtable.h
index a8cf149873b..28c487a71c2 100644
--- a/libstdc++-v3/include/backward/hashtable.h
+++ b/libstdc++-v3/include/backward/hashtable.h
@@ -379,7 +379,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const
       { return size_type(-1); }
 
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const
       { return size() == 0; }
 
diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h
index cea28e04500..ed61ce845f8 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -301,7 +301,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *
        *  Calls @c a.allocate(n)
       */
-      static pointer
+      _GLIBCXX_NODISCARD static pointer
       allocate(_Alloc& __a, size_type __n)
       { return __a.allocate(__n); }
 
@@ -316,7 +316,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *  Returns <tt> a.allocate(n, hint) </tt> if that expression is
        *  well-formed, otherwise returns @c a.allocate(n)
       */
-      static pointer
+      _GLIBCXX_NODISCARD static pointer
       allocate(_Alloc& __a, size_type __n, const_void_pointer __hint)
       { return _S_allocate(__a, __n, __hint, 0); }
 
@@ -439,7 +439,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *
        *  Calls @c a.allocate(n)
       */
-      static pointer
+      _GLIBCXX_NODISCARD static pointer
       allocate(allocator_type& __a, size_type __n)
       { return __a.allocate(__n); }
 
@@ -453,7 +453,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *
        *  Returns <tt> a.allocate(n, hint) </tt>
       */
-      static pointer
+      _GLIBCXX_NODISCARD static pointer
       allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
       { return __a.allocate(__n, __hint); }
 
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index 28ed337bdb6..0a6dd3cbc71 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -1027,7 +1027,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CXX11
        *  Returns true if the %string is empty.  Equivalent to 
        *  <code>*this == ""</code>.
        */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const _GLIBCXX_NOEXCEPT
       { return this->size() == 0; }
 
@@ -4007,7 +4007,7 @@  _GLIBCXX_END_NAMESPACE_CXX11
        *  Returns true if the %string is empty.  Equivalent to 
        *  <code>*this == ""</code>.
        */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const _GLIBCXX_NOEXCEPT
       { return this->size() == 0; }
 
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index 4741c43376c..4c277845a51 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -774,7 +774,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  Returns true if the %forward_list is empty.  (Thus begin() would
        *  equal end().)
        */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const noexcept
       { return this->_M_impl._M_head._M_next == nullptr; }
 
diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index 34946c75b0b..31794fb12c2 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -533,7 +533,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       size() const noexcept
       { return _M_element_count; }
 
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const noexcept
       { return size() == 0; }
 
diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h
index 79645948af2..7576cd7a9c0 100644
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -1705,7 +1705,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CXX11
        * @retval true The %match_results object is empty.
        * @retval false The %match_results object is not empty.
        */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const noexcept
       { return size() == 0; }
 
diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h
index 341682c03a5..1574895a2c6 100644
--- a/libstdc++-v3/include/bits/stl_deque.h
+++ b/libstdc++-v3/include/bits/stl_deque.h
@@ -1377,7 +1377,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  Returns true if the %deque is empty.  (Thus begin() would
        *  equal end().)
        */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const _GLIBCXX_NOEXCEPT
       { return this->_M_impl._M_finish == this->_M_impl._M_start; }
 
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index 14a7881d0f5..68bab94af1e 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -1047,7 +1047,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CXX11
        *  Returns true if the %list is empty.  (Thus begin() would equal
        *  end().)
        */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const _GLIBCXX_NOEXCEPT
       { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; }
 
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index c2c974a2003..a61d23cac68 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -459,7 +459,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /** Returns true if the %map is empty.  (Thus begin() would equal
        *  end().)
       */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const _GLIBCXX_NOEXCEPT
       { return _M_t.empty(); }
 
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 98796fd2878..29a96d8a45b 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -452,7 +452,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       // capacity
       /** Returns true if the %multimap is empty.  */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const _GLIBCXX_NOEXCEPT
       { return _M_t.empty(); }
 
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index 175e0755543..7a0fb832480 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -406,7 +406,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 #endif
 
       ///  Returns true if the %set is empty.
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const _GLIBCXX_NOEXCEPT
       { return _M_t.empty(); }
 
diff --git a/libstdc++-v3/include/bits/stl_queue.h b/libstdc++-v3/include/bits/stl_queue.h
index 575cbf9bed8..aa8dd02ed6e 100644
--- a/libstdc++-v3/include/bits/stl_queue.h
+++ b/libstdc++-v3/include/bits/stl_queue.h
@@ -185,7 +185,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       /**
        *  Returns true if the %queue is empty.
        */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const
       { return c.empty(); }
 
@@ -563,7 +563,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       /**
        *  Returns true if the %queue is empty.
        */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const
       { return c.empty(); }
 
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 7779007c2e2..7c903cf3a9a 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -410,7 +410,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 #endif
 
       ///  Returns true if the %set is empty.
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const _GLIBCXX_NOEXCEPT
       { return _M_t.empty(); }
 
diff --git a/libstdc++-v3/include/bits/stl_stack.h b/libstdc++-v3/include/bits/stl_stack.h
index 88650c15ba6..8581dce210c 100644
--- a/libstdc++-v3/include/bits/stl_stack.h
+++ b/libstdc++-v3/include/bits/stl_stack.h
@@ -181,7 +181,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       /**
        *  Returns true if the %stack is empty.
        */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const
       { return c.empty(); }
 
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 252ef959fcc..47ae0ae9531 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -1027,7 +1027,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       rend() const _GLIBCXX_NOEXCEPT
       { return const_reverse_iterator(begin()); }
 
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const _GLIBCXX_NOEXCEPT
       { return _M_impl._M_node_count == 0; }
 
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index ebf105aa8fa..54de0e09ce7 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -964,7 +964,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  Returns true if the %vector is empty.  (Thus begin() would
        *  equal end().)
        */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const _GLIBCXX_NOEXCEPT
       { return begin() == end(); }
 
diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h
index 4b71db5d10a..ecb3ef411fc 100644
--- a/libstdc++-v3/include/bits/unordered_map.h
+++ b/libstdc++-v3/include/bits/unordered_map.h
@@ -300,7 +300,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       // size and capacity:
 
       ///  Returns true if the %unordered_map is empty.
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const noexcept
       { return _M_h.empty(); }
 
@@ -1441,7 +1441,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       // size and capacity:
 
       ///  Returns true if the %unordered_multimap is empty.
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const noexcept
       { return _M_h.empty(); }
 
diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h
index e1ac398e363..3e1180f323a 100644
--- a/libstdc++-v3/include/bits/unordered_set.h
+++ b/libstdc++-v3/include/bits/unordered_set.h
@@ -294,7 +294,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       // size and capacity:
 
       ///  Returns true if the %unordered_set is empty.
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const noexcept
       { return _M_h.empty(); }
 
@@ -1102,7 +1102,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       // size and capacity:
 
       ///  Returns true if the %unordered_multiset is empty.
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const noexcept
       { return _M_h.empty(); }
 
diff --git a/libstdc++-v3/include/debug/array b/libstdc++-v3/include/debug/array
index 0ca2fcae937..9e94e656c04 100644
--- a/libstdc++-v3/include/debug/array
+++ b/libstdc++-v3/include/debug/array
@@ -71,7 +71,7 @@  namespace __debug
       template<std::size_t _Size>
 	struct _Array_check_nonempty
  	{
-	  bool empty() { return _Size == 0; }
+	  _GLIBCXX_NODISCARD bool empty() { return _Size == 0; }
 
 	  _Array_check_nonempty()
 	  { __glibcxx_check_nonempty(); }
@@ -145,7 +145,7 @@  namespace __debug
       constexpr size_type
       max_size() const noexcept { return _Nm; }
 
-      constexpr bool
+      _GLIBCXX_NODISCARD constexpr bool
       empty() const noexcept { return size() == 0; }
 
       // Element access.
diff --git a/libstdc++-v3/include/experimental/any b/libstdc++-v3/include/experimental/any
index f8cd4a78821..ed7a115f6b2 100644
--- a/libstdc++-v3/include/experimental/any
+++ b/libstdc++-v3/include/experimental/any
@@ -266,7 +266,7 @@  inline namespace fundamentals_v1
     // observers
 
     /// Reports whether there is a contained object or not.
-    bool empty() const noexcept { return _M_manager == nullptr; }
+    _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_manager == nullptr; }
 
 #if __cpp_rtti
     /// The @c typeid of the contained object, or @c typeid(void) if empty.
diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h
index e9d6619876a..239776df313 100644
--- a/libstdc++-v3/include/experimental/bits/fs_path.h
+++ b/libstdc++-v3/include/experimental/bits/fs_path.h
@@ -365,7 +365,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CXX11
 
     // query
 
-    bool empty() const noexcept { return _M_pathname.empty(); }
+    _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_pathname.empty(); }
     bool has_root_name() const;
     bool has_root_directory() const;
     bool has_root_path() const;
diff --git a/libstdc++-v3/include/experimental/internet b/libstdc++-v3/include/experimental/internet
index 07c62e697cd..80682efed53 100644
--- a/libstdc++-v3/include/experimental/internet
+++ b/libstdc++-v3/include/experimental/internet
@@ -1049,7 +1049,7 @@  namespace ip
 
     iterator begin() const noexcept { return _M_begin; }
     iterator end() const noexcept { return _M_end; }
-    bool empty() const noexcept { return _M_begin == _M_end; }
+    _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_begin == _M_end; }
 
     size_t
     size() const noexcept { return _M_end->to_uint() - _M_begin->to_uint(); }
@@ -1093,7 +1093,7 @@  namespace ip
 
     iterator begin() const noexcept { return _M_begin; }
     iterator end() const noexcept { return _M_end; }
-    bool empty() const noexcept { return _M_begin == _M_end; }
+    _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_begin == _M_end; }
 
     iterator
     find(const address_v6& __addr) const noexcept
@@ -1721,7 +1721,7 @@  namespace ip
       // size:
       size_type size() const noexcept { return _M_size; }
       size_type max_size() const noexcept { return _M_results.max_size(); }
-      bool empty() const noexcept { return _M_results.empty(); }
+      _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_results.empty(); }
 
       // element access:
       const_iterator begin() const { return _M_results.begin(); }
diff --git a/libstdc++-v3/include/experimental/memory_resource b/libstdc++-v3/include/experimental/memory_resource
index 4d96466f218..e9fece55cd0 100644
--- a/libstdc++-v3/include/experimental/memory_resource
+++ b/libstdc++-v3/include/experimental/memory_resource
@@ -88,7 +88,7 @@  namespace pmr {
 
     memory_resource& operator=(const memory_resource&) = default;
 
-    void*
+    _GLIBCXX_NODISCARD void*
     allocate(size_t __bytes, size_t __alignment = _S_max_align)
     { return do_allocate(__bytes, __alignment); }
 
@@ -145,7 +145,7 @@  namespace pmr {
       polymorphic_allocator&
 	operator=(const polymorphic_allocator& __rhs) = default;
 
-      _Tp* allocate(size_t __n)
+      _GLIBCXX_NODISCARD _Tp* allocate(size_t __n)
       { return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp),
 						       alignof(_Tp))); }
 
diff --git a/libstdc++-v3/include/experimental/string_view b/libstdc++-v3/include/experimental/string_view
index d233ecc743b..8cc0e90246b 100644
--- a/libstdc++-v3/include/experimental/string_view
+++ b/libstdc++-v3/include/experimental/string_view
@@ -169,7 +169,7 @@  inline namespace fundamentals_v1
 		/ sizeof(value_type) / 4;
       }
 
-      constexpr bool
+      _GLIBCXX_NODISCARD constexpr bool
       empty() const noexcept
       { return this->_M_len == 0; }
 
diff --git a/libstdc++-v3/include/ext/alloc_traits.h b/libstdc++-v3/include/ext/alloc_traits.h
index 5571d2692fb..65fa3de271c 100644
--- a/libstdc++-v3/include/ext/alloc_traits.h
+++ b/libstdc++-v3/include/ext/alloc_traits.h
@@ -128,7 +128,7 @@  template<typename _Alloc, typename = typename _Alloc::value_type>
     typedef typename _Alloc::size_type              size_type;
     typedef typename _Alloc::difference_type        difference_type;
 
-    static pointer
+    _GLIBCXX_NODISCARD static pointer
     allocate(_Alloc& __a, size_type __n)
     { return __a.allocate(__n); }
 
diff --git a/libstdc++-v3/include/ext/array_allocator.h b/libstdc++-v3/include/ext/array_allocator.h
index 6dd23cdbb82..c0d4a3497dc 100644
--- a/libstdc++-v3/include/ext/array_allocator.h
+++ b/libstdc++-v3/include/ext/array_allocator.h
@@ -151,7 +151,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       ~array_allocator() _GLIBCXX_USE_NOEXCEPT { }
 
-      pointer
+      _GLIBCXX_NODISCARD pointer
       allocate(size_type __n, const void* = 0)
       {
 	if (_M_array == 0 || _M_used + __n > _M_array->size())
diff --git a/libstdc++-v3/include/ext/bitmap_allocator.h b/libstdc++-v3/include/ext/bitmap_allocator.h
index 400030bfbc5..532bad295b6 100644
--- a/libstdc++-v3/include/ext/bitmap_allocator.h
+++ b/libstdc++-v3/include/ext/bitmap_allocator.h
@@ -90,7 +90,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_M_space_left() const throw()
 	{ return _M_end_of_storage - _M_finish; }
 
-	pointer
+	_GLIBCXX_NODISCARD pointer
 	allocate(size_type __n)
 	{ return static_cast<pointer>(::operator new(__n * sizeof(_Tp))); }
 
@@ -1009,7 +1009,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       ~bitmap_allocator() _GLIBCXX_USE_NOEXCEPT
       { }
 
-      pointer 
+      _GLIBCXX_NODISCARD pointer 
       allocate(size_type __n)
       {
 	if (__n > this->max_size())
@@ -1033,7 +1033,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  }
       }
 
-      pointer 
+      _GLIBCXX_NODISCARD pointer 
       allocate(size_type __n, typename bitmap_allocator<void>::const_pointer)
       { return allocate(__n); }
 
diff --git a/libstdc++-v3/include/ext/debug_allocator.h b/libstdc++-v3/include/ext/debug_allocator.h
index bf86470e8fc..c5fc57e68dd 100644
--- a/libstdc++-v3/include/ext/debug_allocator.h
+++ b/libstdc++-v3/include/ext/debug_allocator.h
@@ -118,7 +118,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       debug_allocator(const _Alloc& __a)
       : _M_allocator(__a), _M_extra(_S_extra()) { }
 
-      pointer
+      _GLIBCXX_NODISCARD pointer
       allocate(size_type __n)
       {
         pointer __res = _M_allocator.allocate(__n + _M_extra);      
@@ -127,7 +127,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
         return __res + _M_extra;
       }
 
-      pointer
+      _GLIBCXX_NODISCARD pointer
       allocate(size_type __n, const void* __hint)
       {
         pointer __res = _M_allocator.allocate(__n + _M_extra, __hint);
diff --git a/libstdc++-v3/include/ext/extptr_allocator.h b/libstdc++-v3/include/ext/extptr_allocator.h
index 388edb2e622..2ce87b60c44 100644
--- a/libstdc++-v3/include/ext/extptr_allocator.h
+++ b/libstdc++-v3/include/ext/extptr_allocator.h
@@ -92,7 +92,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT
       { return std::__addressof(__x); }
 
-      pointer allocate(size_type __n, void* __hint = 0)
+      _GLIBCXX_NODISCARD pointer allocate(size_type __n, void* __hint = 0)
       { return _M_real_alloc.allocate(__n,__hint); }
 
       void deallocate(pointer __p, size_type __n)
diff --git a/libstdc++-v3/include/ext/mt_allocator.h b/libstdc++-v3/include/ext/mt_allocator.h
index 7b07533f3df..43e84f47fbd 100644
--- a/libstdc++-v3/include/ext/mt_allocator.h
+++ b/libstdc++-v3/include/ext/mt_allocator.h
@@ -665,7 +665,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       ~__mt_alloc() _GLIBCXX_USE_NOEXCEPT { }
 
-      pointer
+      _GLIBCXX_NODISCARD pointer
       allocate(size_type __n, const void* = 0);
 
       void
@@ -684,7 +684,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   template<typename _Tp, typename _Poolp>
-    typename __mt_alloc<_Tp, _Poolp>::pointer
+    _GLIBCXX_NODISCARD typename __mt_alloc<_Tp, _Poolp>::pointer
     __mt_alloc<_Tp, _Poolp>::
     allocate(size_type __n, const void*)
     {
diff --git a/libstdc++-v3/include/ext/new_allocator.h b/libstdc++-v3/include/ext/new_allocator.h
index 04db4bbc99f..e24539100f9 100644
--- a/libstdc++-v3/include/ext/new_allocator.h
+++ b/libstdc++-v3/include/ext/new_allocator.h
@@ -98,7 +98,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       // NB: __n is permitted to be 0.  The C++ standard says nothing
       // about what the return value is when __n == 0.
-      pointer
+      _GLIBCXX_NODISCARD pointer
       allocate(size_type __n, const void* = static_cast<const void*>(0))
       {
 	if (__n > this->max_size())
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp
index 5e739551c52..4019f864307 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp
@@ -39,6 +39,7 @@ 
  */
 
 PB_DS_CLASS_T_DEC
+_GLIBCXX_NODISCARD
 inline bool
 PB_DS_CLASS_C_DEC::
 empty() const
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp b/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp
index 40ddeed5aad..dbfd612917e 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp
@@ -144,7 +144,7 @@  namespace __gnu_pbds
 
       ~binary_heap();
 
-      inline bool
+      _GLIBCXX_NODISCARD inline bool
       empty() const;
 
       inline size_type
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp
index 29612faf13e..d81d5500659 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp
@@ -39,6 +39,7 @@ 
  */
 
 PB_DS_CLASS_T_DEC
+_GLIBCXX_NODISCARD
 inline bool
 PB_DS_CLASS_C_DEC::
 empty() const
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp b/libstdc++-v3/include/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp
index 6706c1aab6e..1a6affc70b2 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp
@@ -271,7 +271,7 @@  namespace __gnu_pbds
       max_size() const;
 
       /// True if size() == 0.
-      inline bool
+      _GLIBCXX_NODISCARD inline bool
       empty() const;
 
       /// Return current hash_fn.
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp
index 7b5318b64ec..9d38890f7f6 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp
@@ -52,6 +52,7 @@  max_size() const
 { return m_entry_allocator.max_size(); }
 
 PB_DS_CLASS_T_DEC
+_GLIBCXX_NODISCARD
 inline bool
 PB_DS_CLASS_C_DEC::
 empty() const
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp
index 500b92f0be0..bcc1fc47b12 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp
@@ -46,6 +46,7 @@  size() const
 { return m_num_used_e; }
 
 PB_DS_CLASS_T_DEC
+_GLIBCXX_NODISCARD
 inline bool
 PB_DS_CLASS_C_DEC::
 empty() const
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp b/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp
index bcac913597d..90dfd50ef8e 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp
@@ -279,7 +279,7 @@  namespace __gnu_pbds
       max_size() const;
 
       /// True if size() == 0.
-      inline bool
+      _GLIBCXX_NODISCARD inline bool
       empty() const;
 
       /// Return current hash_fn.
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp
index 64fa975e601..464216e45dd 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp
@@ -52,6 +52,7 @@  max_size() const
 { return s_entry_allocator.max_size(); }
 
 PB_DS_CLASS_T_DEC
+_GLIBCXX_NODISCARD
 inline bool
 PB_DS_CLASS_C_DEC::
 empty() const
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp
index 8d31e5b711d..d12710a1218 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp
@@ -39,6 +39,7 @@ 
  */
 
 PB_DS_CLASS_T_DEC
+_GLIBCXX_NODISCARD
 inline bool
 PB_DS_CLASS_C_DEC::
 empty() const
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp b/libstdc++-v3/include/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp
index 746a3d8a39a..32d67eb3d3a 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp
@@ -144,7 +144,7 @@  namespace __gnu_pbds
 
       ~left_child_next_sibling_heap();
 
-      inline bool
+      _GLIBCXX_NODISCARD inline bool
       empty() const;
 
       inline size_type
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp
index 2c44a513c82..5d2e81ff4a7 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp
@@ -51,6 +51,7 @@  max_size() const
 { return s_entry_allocator.max_size(); }
 
 PB_DS_CLASS_T_DEC
+_GLIBCXX_NODISCARD
 inline bool
 PB_DS_CLASS_C_DEC::
 empty() const
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/list_update_map_/lu_map_.hpp b/libstdc++-v3/include/ext/pb_ds/detail/list_update_map_/lu_map_.hpp
index e3539a57516..a3c0fb49c9a 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/list_update_map_/lu_map_.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/list_update_map_/lu_map_.hpp
@@ -198,7 +198,7 @@  namespace __gnu_pbds
       inline size_type
       max_size() const;
 
-      inline bool
+      _GLIBCXX_NODISCARD inline bool
       empty() const;
 
       inline mapped_reference
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp
index 26f33bf5444..81e7305e315 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp
@@ -54,6 +54,7 @@  max_size() const
 { return s_value_alloc.max_size(); }
 
 PB_DS_CLASS_T_DEC
+_GLIBCXX_NODISCARD
 inline bool
 PB_DS_CLASS_C_DEC::
 empty() const
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp b/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp
index efebc354cd6..0859da17d7a 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp
@@ -239,7 +239,7 @@  namespace __gnu_pbds
       inline size_type
       max_size() const;
 
-      inline bool
+      _GLIBCXX_NODISCARD inline bool
       empty() const;
 
       inline size_type
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp
index 0f6eaf5c44a..33fc3e14ccf 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp
@@ -39,6 +39,7 @@ 
  */
 
 PB_DS_CLASS_T_DEC
+_GLIBCXX_NODISCARD
 inline bool
 PB_DS_CLASS_C_DEC::
 empty() const
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp b/libstdc++-v3/include/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp
index 13da3d4264a..3f7e054e249 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp
@@ -223,7 +223,7 @@  namespace __gnu_pbds
 	    }
 	}
 
-	inline bool
+	_GLIBCXX_NODISCARD inline bool
 	empty() const
 	{ return m_bag.empty(); }
       };
@@ -279,7 +279,7 @@  namespace __gnu_pbds
 
       ~PB_DS_PAT_TRIE_NAME();
 
-      inline bool
+      _GLIBCXX_NODISCARD inline bool
       empty() const;
 
       inline size_type
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp b/libstdc++-v3/include/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp
index 2d1b4e795a3..5c996d11e28 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp
@@ -87,7 +87,7 @@  namespace __gnu_pbds
       inline void
       pop();
 
-      inline bool
+      _GLIBCXX_NODISCARD inline bool
       empty() const;
 
       inline size_type
@@ -178,7 +178,7 @@  namespace __gnu_pbds
     }
 
     template<typename _Node, typename _Alloc>
-    inline bool
+    _GLIBCXX_NODISCARD inline bool
     rc<_Node, _Alloc>::
     empty() const
     {
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/tree_trace_base.hpp b/libstdc++-v3/include/ext/pb_ds/detail/tree_trace_base.hpp
index 980ff9788a2..3b349c70d35 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/tree_trace_base.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/tree_trace_base.hpp
@@ -80,7 +80,7 @@  namespace __gnu_pbds
       void
       trace_node(node_const_iterator, size_type) const;
 
-      virtual bool
+      _GLIBCXX_NODISCARD virtual bool
       empty() const = 0;
 
       virtual node_const_iterator
diff --git a/libstdc++-v3/include/ext/pb_ds/trie_policy.hpp b/libstdc++-v3/include/ext/pb_ds/trie_policy.hpp
index 0b0683dec51..9c750aa56b3 100644
--- a/libstdc++-v3/include/ext/pb_ds/trie_policy.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/trie_policy.hpp
@@ -315,7 +315,7 @@  namespace __gnu_pbds
     typedef typename __rebind_ma::reference 		metadata_reference;
 
     /// Returns true if the container is empty.
-    virtual bool
+    _GLIBCXX_NODISCARD virtual bool
     empty() const = 0;
 
     /// Returns the iterator associated with the trie's first element.
diff --git a/libstdc++-v3/include/ext/pool_allocator.h b/libstdc++-v3/include/ext/pool_allocator.h
index 460f55dbbf0..4b23727abae 100644
--- a/libstdc++-v3/include/ext/pool_allocator.h
+++ b/libstdc++-v3/include/ext/pool_allocator.h
@@ -188,7 +188,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       destroy(pointer __p) { __p->~_Tp(); }
 #endif
 
-      pointer
+      _GLIBCXX_NODISCARD pointer
       allocate(size_type __n, const void* = 0);
 
       void
@@ -210,7 +210,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __pool_alloc<_Tp>::_S_force_new;
 
   template<typename _Tp>
-    _Tp*
+    _GLIBCXX_NODISCARD _Tp*
     __pool_alloc<_Tp>::allocate(size_type __n, const void*)
     {
       pointer __ret = 0;
diff --git a/libstdc++-v3/include/ext/rope b/libstdc++-v3/include/ext/rope
index 4cc8285a671..127d113c349 100644
--- a/libstdc++-v3/include/ext/rope
+++ b/libstdc++-v3/include/ext/rope
@@ -1797,7 +1797,7 @@  protected:
       static int _S_compare(const _RopeRep* __x, const _RopeRep* __y);
       
     public:
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const
       { return 0 == this->_M_tree_ptr; }
       
diff --git a/libstdc++-v3/include/ext/slist b/libstdc++-v3/include/ext/slist
index 532235f8c53..3b49ae20183 100644
--- a/libstdc++-v3/include/ext/slist
+++ b/libstdc++-v3/include/ext/slist
@@ -458,7 +458,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const
       { return size_type(-1); }
 
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const
       { return this->_M_head._M_next == 0; }
 
diff --git a/libstdc++-v3/include/ext/throw_allocator.h b/libstdc++-v3/include/ext/throw_allocator.h
index 52d58e6ffc6..38e80f721da 100644
--- a/libstdc++-v3/include/ext/throw_allocator.h
+++ b/libstdc++-v3/include/ext/throw_allocator.h
@@ -829,7 +829,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       address(const_reference __x) const _GLIBCXX_NOEXCEPT
       { return std::__addressof(__x); }
 
-      pointer
+      _GLIBCXX_NODISCARD pointer
       allocate(size_type __n, std::allocator<void>::const_pointer hint = 0)
       {
 	if (__n > this->max_size())
diff --git a/libstdc++-v3/include/ext/vstring.h b/libstdc++-v3/include/ext/vstring.h
index ddffebf0893..5942218531f 100644
--- a/libstdc++-v3/include/ext/vstring.h
+++ b/libstdc++-v3/include/ext/vstring.h
@@ -518,7 +518,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *  Returns true if the %string is empty.  Equivalent to 
        *  <code>*this == ""</code>.
        */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const _GLIBCXX_NOEXCEPT
       { return this->size() == 0; }
 
diff --git a/libstdc++-v3/include/profile/array b/libstdc++-v3/include/profile/array
index dc7b594e29d..8f80e2a067f 100644
--- a/libstdc++-v3/include/profile/array
+++ b/libstdc++-v3/include/profile/array
@@ -124,7 +124,7 @@  namespace __profile
       constexpr size_type
       max_size() const noexcept { return _Nm; }
 
-      constexpr bool
+      _GLIBCXX_NODISCARD constexpr bool
       empty() const noexcept { return size() == 0; }
 
       // Element access.
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index ba52e3c2c89..02c6f4b4dbe 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -177,7 +177,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       constexpr size_type
       max_size() const noexcept { return _Nm; }
 
-      constexpr bool
+      _GLIBCXX_NODISCARD constexpr bool
       empty() const noexcept { return size() == 0; }
 
       // Element access.
diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future
index 6cafde5ee6a..10136e57a84 100644
--- a/libstdc++-v3/include/std/future
+++ b/libstdc++-v3/include/std/future
@@ -1703,7 +1703,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// async
   template<typename _Fn, typename... _Args>
-    future<__async_result_of<_Fn, _Args...>>
+    _GLIBCXX_NODISCARD future<__async_result_of<_Fn, _Args...>>
     async(launch __policy, _Fn&& __fn, _Args&&... __args)
     {
       std::shared_ptr<__future_base::_State_base> __state;
@@ -1736,7 +1736,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// async, potential overload
   template<typename _Fn, typename... _Args>
-    inline future<__async_result_of<_Fn, _Args...>>
+    _GLIBCXX_NODISCARD inline future<__async_result_of<_Fn, _Args...>>
     async(_Fn&& __fn, _Args&&... __args)
     {
       return std::async(launch::async|launch::deferred,
diff --git a/libstdc++-v3/include/std/scoped_allocator b/libstdc++-v3/include/std/scoped_allocator
index 5a8495db21b..335df483f69 100644
--- a/libstdc++-v3/include/std/scoped_allocator
+++ b/libstdc++-v3/include/std/scoped_allocator
@@ -343,10 +343,10 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       const outer_allocator_type& outer_allocator() const noexcept
       { return static_cast<const _OuterAlloc&>(*this); }
 
-      pointer allocate(size_type __n)
+      _GLIBCXX_NODISCARD pointer allocate(size_type __n)
       { return __traits::allocate(outer_allocator(), __n); }
 
-      pointer allocate(size_type __n, const_void_pointer __hint)
+      _GLIBCXX_NODISCARD pointer allocate(size_type __n, const_void_pointer __hint)
       { return __traits::allocate(outer_allocator(), __n, __hint); }
 
       void deallocate(pointer __p, size_type __n)
diff --git a/libstdc++-v3/include/tr1/array b/libstdc++-v3/include/tr1/array
index e8266d7bc03..5c0857b960e 100644
--- a/libstdc++-v3/include/tr1/array
+++ b/libstdc++-v3/include/tr1/array
@@ -119,7 +119,7 @@  namespace tr1
       size_type 
       max_size() const { return _Nm; }
 
-      bool 
+      _GLIBCXX_NODISCARD bool 
       empty() const { return size() == 0; }
 
       // Element access.
diff --git a/libstdc++-v3/include/tr1/hashtable.h b/libstdc++-v3/include/tr1/hashtable.h
index eed79effb3c..c1b5c9e8fda 100644
--- a/libstdc++-v3/include/tr1/hashtable.h
+++ b/libstdc++-v3/include/tr1/hashtable.h
@@ -244,7 +244,7 @@  namespace tr1
       size() const
       { return _M_element_count; }
 
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const
       { return size() == 0; }
 
diff --git a/libstdc++-v3/include/tr1/regex b/libstdc++-v3/include/tr1/regex
index f0d0742860f..73c610d2bbd 100644
--- a/libstdc++-v3/include/tr1/regex
+++ b/libstdc++-v3/include/tr1/regex
@@ -1870,7 +1870,7 @@  namespace regex_constants
        * @retval true The %match_results object is empty.
        * @retval false The %match_results object is not empty.
        */
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const
       { return size() == 0; }
       
diff --git a/libstdc++-v3/include/tr2/dynamic_bitset b/libstdc++-v3/include/tr2/dynamic_bitset
index fb022f3b188..434a4cc87ec 100644
--- a/libstdc++-v3/include/tr2/dynamic_bitset
+++ b/libstdc++-v3/include/tr2/dynamic_bitset
@@ -1014,7 +1014,7 @@  namespace tr2
       { return this->_M_size(); }
 
       /// Returns true if the dynamic_bitset is empty.
-      bool
+      _GLIBCXX_NODISCARD bool
       empty() const noexcept
       { return (this->_M_Nb == 0); }
 
diff --git a/libstdc++-v3/libsupc++/eh_alloc.cc b/libstdc++-v3/libsupc++/eh_alloc.cc
index ad16699e7b8..005c28dbb11 100644
--- a/libstdc++-v3/libsupc++/eh_alloc.cc
+++ b/libstdc++-v3/libsupc++/eh_alloc.cc
@@ -86,7 +86,7 @@  namespace
     public:
       pool();
 
-      void *allocate (std::size_t);
+      _GLIBCXX_NODISCARD void *allocate (std::size_t);
       void free (void *);
 
       bool in_pool (void *);
diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new
index a35972b08b3..6347d21b26f 100644
--- a/libstdc++-v3/libsupc++/new
+++ b/libstdc++-v3/libsupc++/new
@@ -122,9 +122,9 @@  namespace std
  *  Placement new and delete signatures (take a memory address argument,
  *  does nothing) may not be replaced by a user's program.
 */
-void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc)
+_GLIBCXX_NODISCARD void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc)
   __attribute__((__externally_visible__));
-void* operator new[](std::size_t) _GLIBCXX_THROW (std::bad_alloc)
+_GLIBCXX_NODISCARD void* operator new[](std::size_t) _GLIBCXX_THROW (std::bad_alloc)
   __attribute__((__externally_visible__));
 void operator delete(void*) _GLIBCXX_USE_NOEXCEPT
   __attribute__((__externally_visible__));
@@ -136,26 +136,26 @@  void operator delete(void*, std::size_t) _GLIBCXX_USE_NOEXCEPT
 void operator delete[](void*, std::size_t) _GLIBCXX_USE_NOEXCEPT
   __attribute__((__externally_visible__));
 #endif
-void* operator new(std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
+_GLIBCXX_NODISCARD void* operator new(std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
   __attribute__((__externally_visible__, __malloc__));
-void* operator new[](std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
+_GLIBCXX_NODISCARD void* operator new[](std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
   __attribute__((__externally_visible__, __malloc__));
 void operator delete(void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
   __attribute__((__externally_visible__));
 void operator delete[](void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
   __attribute__((__externally_visible__));
 #if __cpp_aligned_new
-void* operator new(std::size_t, std::align_val_t)
+_GLIBCXX_NODISCARD void* operator new(std::size_t, std::align_val_t)
   __attribute__((__externally_visible__));
-void* operator new(std::size_t, std::align_val_t, const std::nothrow_t&)
+_GLIBCXX_NODISCARD void* operator new(std::size_t, std::align_val_t, const std::nothrow_t&)
   _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__, __malloc__));
 void operator delete(void*, std::align_val_t)
   _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
 void operator delete(void*, std::align_val_t, const std::nothrow_t&)
   _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
-void* operator new[](std::size_t, std::align_val_t)
+_GLIBCXX_NODISCARD void* operator new[](std::size_t, std::align_val_t)
   __attribute__((__externally_visible__));
-void* operator new[](std::size_t, std::align_val_t, const std::nothrow_t&)
+_GLIBCXX_NODISCARD void* operator new[](std::size_t, std::align_val_t, const std::nothrow_t&)
   _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__, __malloc__));
 void operator delete[](void*, std::align_val_t)
   _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
@@ -170,9 +170,9 @@  void operator delete[](void*, std::size_t, std::align_val_t)
 #endif // __cpp_aligned_new
 
 // Default placement versions of operator new.
-inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
+_GLIBCXX_NODISCARD inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
 { return __p; }
-inline void* operator new[](std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
+_GLIBCXX_NODISCARD inline void* operator new[](std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
 { return __p; }
 
 // Default placement versions of operator delete.