[committed] libstdc++: Disable volatile-qualified std::bind for C++20

Message ID 20220928233634.2670028-1-jwakely@redhat.com
State New, archived
Headers
Series [committed] libstdc++: Disable volatile-qualified std::bind for C++20 |

Commit Message

Jonathan Wakely Sept. 28, 2022, 11:36 p.m. UTC
  Tested powerpc64le-linux. Pushed to trunk.

-- >8 --

LWG 2487 added a precondition to std::bind for C++17, making
volatile-qualified uses undefined. We still support it, but with a
deprecated warning.

P1065R2 made it explicitly ill-formed for C++20, so we should no longer
accept it as deprecated. This implements that change.

libstdc++-v3/ChangeLog:

	* doc/xml/manual/evolution.xml: Document std::bind API
	changes.
	* doc/xml/manual/intro.xml: Document LWG 2487 status.
	* doc/xml/manual/using.xml: Clarify default value of
	_GLIBCXX_USE_DEPRECATED.
	* doc/html/*: Regenerate.
	* include/std/functional (_Bind::operator()(Args&&...) volatile)
	(_Bind::operator()(Args&&...) const volatile)
	(_Bind_result::operator()(Args&&...) volatile)
	(_Bind_result::operator()(Args&&...) const volatile): Replace
	with deleted overload for C++20 and later.
	* testsuite/20_util/bind/cv_quals.cc: Check for deprecated
	warnings in C++17.
	* testsuite/20_util/bind/cv_quals_2.cc: Likewise, and check for
	ill-formed in C++20.
---
 libstdc++-v3/doc/html/index.html              |  2 +-
 libstdc++-v3/doc/html/manual/api.html         |  5 +++
 libstdc++-v3/doc/html/manual/appendix.html    |  2 +-
 .../doc/html/manual/appendix_porting.html     |  2 +-
 libstdc++-v3/doc/html/manual/bugs.html        |  6 ++++
 libstdc++-v3/doc/html/manual/index.html       |  2 +-
 .../doc/html/manual/using_macros.html         |  5 +--
 libstdc++-v3/doc/xml/manual/evolution.xml     | 13 ++++++++
 libstdc++-v3/doc/xml/manual/intro.xml         |  9 ++++++
 libstdc++-v3/doc/xml/manual/using.xml         |  5 +--
 libstdc++-v3/include/std/functional           | 32 ++++++++++++++-----
 .../testsuite/20_util/bind/cv_quals.cc        | 25 ++++++++-------
 .../testsuite/20_util/bind/cv_quals_2.cc      | 12 ++++---
 13 files changed, 87 insertions(+), 33 deletions(-)
  

Patch

diff --git a/libstdc++-v3/doc/xml/manual/evolution.xml b/libstdc++-v3/doc/xml/manual/evolution.xml
index 4923e8c4783..82936189179 100644
--- a/libstdc++-v3/doc/xml/manual/evolution.xml
+++ b/libstdc++-v3/doc/xml/manual/evolution.xml
@@ -817,6 +817,10 @@  now defaults to zero.
   <classname>has_trivial_copy_assign</classname> removed.
 </para>
 
+<para>
+Calling a <code>std::bind</code> result as volatile was deprecated for C++17.
+</para>
+
 <para> Profile Mode was deprecated. </para>
 
 <section xml:id="api.rel_72"><info><title><constant>7.2</constant></title></info>
@@ -1067,4 +1071,13 @@  the process.
 
 </section>
 
+
+<section xml:id="api.rel_123"><info><title><constant>12.3</constant></title></info>
+<para>
+Calling a <code>std::bind</code> result as volatile is ill-formed for C++20
+and later.
+</para>
+
+</section>
+
 </section>
diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml
index d341c3efe6d..e3a03cf9d59 100644
--- a/libstdc++-v3/doc/xml/manual/intro.xml
+++ b/libstdc++-v3/doc/xml/manual/intro.xml
@@ -1163,6 +1163,15 @@  requirements of the license of GCC.
     ill-formed.
     </para></listitem></varlistentry>
 
+    <varlistentry xml:id="manual.bugs.dr2487"><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&DR;#2487">2487</link>:
+       <emphasis><code>bind()</code> should be <code>const</code>-overloaded
+      not cv-overloaded
+       </emphasis>
+    </term>
+    <listitem><para>Deprecate volatile-qualified <code>operator()</code>
+    for C++17, make it ill-formed for C++20.
+    </para></listitem></varlistentry>
+
     <varlistentry xml:id="manual.bugs.dr2499"><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&DR;#2499">2499</link>:
        <emphasis><code>operator>>(basic_istream&amp;, CharT*)</code> makes it hard to avoid buffer overflows
        </emphasis>
diff --git a/libstdc++-v3/doc/xml/manual/using.xml b/libstdc++-v3/doc/xml/manual/using.xml
index 0acdba6b3bd..9c444dd2997 100644
--- a/libstdc++-v3/doc/xml/manual/using.xml
+++ b/libstdc++-v3/doc/xml/manual/using.xml
@@ -1062,7 +1062,7 @@  g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 hello.cc -o test.exe
       #define/#undef).
    </para>
 
-   <para> <acronym>ABI</acronym> means that changing from the default value may
+   <para> <acronym>ABI</acronym>-changing means that changing from the default value may
   mean changing the <acronym>ABI</acronym> of compiled code. In other words,
   these choices control code which has already been compiled (i.e., in a
   binary such as libstdc++.a/.so).  If you explicitly #define or
@@ -1077,7 +1077,8 @@  g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 hello.cc -o test.exe
     <varlistentry><term><code>_GLIBCXX_USE_DEPRECATED</code></term>
     <listitem>
       <para>
-	Defined by default. Not configurable. ABI-changing. Turning this off
+	Defined to the value <literal>1</literal> by default.
+	Not configurable. ABI-changing. Turning this off
 	removes older ARM-style iostreams code, and other anachronisms
 	from the API.  This macro is dependent on the version of the
 	standard being tracked, and as a result may give different results for
diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index c4f75880fd8..5235ef20332 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -465,6 +465,17 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// @endcond
 
+#if __cplusplus == 201703L && _GLIBCXX_USE_DEPRECATED
+# define _GLIBCXX_VOLATILE_BIND
+// _GLIBCXX_RESOLVE_LIB_DEFECTS
+// 2487. bind() should be const-overloaded, not cv-overloaded
+# define _GLIBCXX_DEPR_BIND \
+      [[deprecated("std::bind does not support volatile in C++17")]]
+#elif __cplusplus < 201703L
+# define _GLIBCXX_VOLATILE_BIND
+# define _GLIBCXX_DEPR_BIND
+#endif
+
   /// Type of the function object returned from bind().
   template<typename _Signature>
     class _Bind;
@@ -501,6 +512,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	      );
 	}
 
+#ifdef _GLIBCXX_VOLATILE_BIND
       // Call as volatile
       template<typename _Result, typename... _Args, std::size_t... _Indexes>
 	_Result
@@ -522,6 +534,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	      _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)...
 	      );
 	}
+#endif // volatile
 
       template<typename _BoundArg, typename _CallArgs>
 	using _Mu_type = decltype(
@@ -585,12 +598,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	      _Bound_indexes());
 	}
 
-#if __cplusplus > 201402L
-# define _GLIBCXX_DEPR_BIND \
-      [[deprecated("std::bind does not support volatile in C++17")]]
-#else
-# define _GLIBCXX_DEPR_BIND
-#endif
+#ifdef _GLIBCXX_VOLATILE_BIND
       // Call as volatile
       template<typename... _Args,
 	       typename _Result = _Res_type_cv<tuple<_Args...>, add_volatile>>
@@ -614,6 +622,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	      std::forward_as_tuple(std::forward<_Args>(__args)...),
 	      _Bound_indexes());
 	}
+#endif // volatile
     };
 
   /// Type of the function object returned from bind<R>().
@@ -649,9 +658,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		      (std::get<_Indexes>(_M_bound_args), __args)...);
 	}
 
+#ifdef _GLIBCXX_VOLATILE_BIND
       // Call as volatile
       template<typename _Res, typename... _Args, std::size_t... _Indexes>
-	_GLIBCXX20_CONSTEXPR
 	_Res
 	__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile
 	{
@@ -661,7 +670,6 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       // Call as const volatile
       template<typename _Res, typename... _Args, std::size_t... _Indexes>
-	_GLIBCXX20_CONSTEXPR
 	_Res
 	__call(tuple<_Args...>&& __args,
 	       _Index_tuple<_Indexes...>) const volatile
@@ -669,6 +677,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return std::__invoke_r<_Res>(_M_f, _Mu<_Bound_args>()
 		      (__volget<_Indexes>(_M_bound_args), __args)...);
 	}
+#endif // volatile
 
     public:
       typedef _Result result_type;
@@ -710,6 +719,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	      _Bound_indexes());
 	}
 
+#ifdef _GLIBCXX_VOLATILE_BIND
       // Call as volatile
       template<typename... _Args>
 	_GLIBCXX_DEPR_BIND
@@ -731,7 +741,13 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	      std::forward_as_tuple(std::forward<_Args>(__args)...),
 	      _Bound_indexes());
 	}
+#else
+      template<typename... _Args>
+	void operator()(_Args&&...) const volatile = delete;
+#endif // volatile
     };
+
+#undef _GLIBCXX_VOLATILE_BIND
 #undef _GLIBCXX_DEPR_BIND
 
   /**
diff --git a/libstdc++-v3/testsuite/20_util/bind/cv_quals.cc b/libstdc++-v3/testsuite/20_util/bind/cv_quals.cc
index 83312397a93..79e3e2fbdb4 100644
--- a/libstdc++-v3/testsuite/20_util/bind/cv_quals.cc
+++ b/libstdc++-v3/testsuite/20_util/bind/cv_quals.cc
@@ -17,6 +17,7 @@ 
 
 // 20.7.11 Function template bind
 
+// { dg-options "-Wdeprecated-declarations" }
 // { dg-do run { target c++11 } }
 
 #include <functional>
@@ -48,12 +49,12 @@  void test01()
   const auto b1 = std::bind(X());
   VERIFY( b1() == 1 );
 
-#if __cplusplus <= 201402L
+#if __cplusplus <= 201703L
   volatile auto b2 = std::bind(X());
-  VERIFY( b2() == 2 );
+  VERIFY( b2() == 2 ); // { dg-warning "deprecated" "" { target c++17_only } }
 
   const volatile auto b3 = std::bind(X());
-  VERIFY( b3() == 3 );
+  VERIFY( b3() == 3 ); // { dg-warning "deprecated" "" { target c++17_only } }
 #endif
 }
 
@@ -65,12 +66,12 @@  void test02()
   const auto b1 = std::bind<int>(X());
   VERIFY( b1() == 1 );
 
-#if __cplusplus <= 201402L
+#if __cplusplus <= 201703L
   volatile auto b2 = std::bind<int>(X());
-  VERIFY( b2() == 2 );
+  VERIFY( b2() == 2 ); // { dg-warning "deprecated" "" { target c++17_only } }
 
   const volatile auto b3 = std::bind<int>(X());
-  VERIFY( b3() == 3 );
+  VERIFY( b3() == 3 ); // { dg-warning "deprecated" "" { target c++17_only } }
 #endif
 }
 
@@ -82,12 +83,12 @@  void test03()
   const auto b1 = std::bind(X(), _1, 0, _2);
   VERIFY( b1(0, 0) == 1 );
 
-#if __cplusplus <= 201402L
+#if __cplusplus <= 201703L
   volatile auto b2 = std::bind(X(), _1, _2, 0);
-  VERIFY( b2(0, 0) == 2 );
+  VERIFY( b2(0, 0) == 2 ); // { dg-warning "deprecated" "" { target c++17_only } }
 
   const volatile auto b3 = std::bind(X(), _1, 0, _2);
-  VERIFY( b3(0, 0) == 3 );
+  VERIFY( b3(0, 0) == 3 ); // { dg-warning "deprecated" "" { target c++17_only } }
 #endif
 }
 
@@ -99,12 +100,12 @@  void test04()
   const auto b1 = std::bind<int>(X(), _1, 0, _2);
   VERIFY( b1(0, 0) == 1 );
 
-#if __cplusplus <= 201402L
+#if __cplusplus <= 201703L
   volatile auto b2 = std::bind<int>(X(), _1, _2, 0);
-  VERIFY( b2(0, 0) == 2 );
+  VERIFY( b2(0, 0) == 2 ); // { dg-warning "deprecated" "" { target c++17_only } }
 
   const volatile auto b3 = std::bind<int>(X(), _1, 0, _2);
-  VERIFY( b3(0, 0) == 3 );
+  VERIFY( b3(0, 0) == 3 ); // { dg-warning "deprecated" "" { target c++17_only } }
 #endif
 }
 
diff --git a/libstdc++-v3/testsuite/20_util/bind/cv_quals_2.cc b/libstdc++-v3/testsuite/20_util/bind/cv_quals_2.cc
index 7a85568c66a..d2ebad72fdf 100644
--- a/libstdc++-v3/testsuite/20_util/bind/cv_quals_2.cc
+++ b/libstdc++-v3/testsuite/20_util/bind/cv_quals_2.cc
@@ -15,7 +15,9 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-do run { target c++11 } }
+// { dg-options "-Wdeprecated-declarations" }
+// { dg-do run { target { c++11 && c++17_down } } }
+// { dg-do compile { target c++20 } }
 
 #include <functional>
 #include <testsuite_hooks.h>
@@ -33,13 +35,13 @@  void test01()
   const auto b0 = std::bind(X());
   VERIFY( b0() == 0 );
 
-#if __cplusplus <= 201402L
   volatile auto b1 = std::bind(X());
-  VERIFY( b1() == 1 );
+  VERIFY( b1() == 1 ); // { dg-warning "deprecated" "" { target c++17_only } }
+		       // { dg-error "no match" "" { target c++20 } 39 }
 
   const volatile auto b2 = std::bind(X());
-  VERIFY( b2() == 2 );
-#endif
+  VERIFY( b2() == 2 ); // { dg-warning "deprecated" "" { target c++17_only } }
+		       // { dg-error "no match" "" { target c++20 } 43 }
 }
 
 int main()