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(-) 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&, 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() -- 2.37.3