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

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.
This commit is contained in:
Jonathan Wakely
2022-09-28 12:39:41 +01:00
parent fa9bda3ea4
commit d01f112de4
13 changed files with 87 additions and 33 deletions

File diff suppressed because one or more lines are too long

View File

@@ -316,6 +316,8 @@ now defaults to zero.
<code class="classname">has_trivial_default_constructor</code>,
<code class="classname">has_trivial_copy_constructor</code> and
<code class="classname">has_trivial_copy_assign</code> removed.
</p><p>
Calling a <code class="code">std::bind</code> result as volatile was deprecated for C++17.
</p><p> Profile Mode was deprecated. </p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="api.rel_72"></a><code class="constant">7.2</code></h4></div></div></div><p>
Library Fundamentals TS header
<code class="filename">&lt;experimental/source_location&gt;</code>
@@ -468,4 +470,7 @@ they both derive from <code class="classname">std::__new_allocator</code> instea
<code class="code">noexcept(false)</code> to allow thread cancellation exceptions to
be thrown from <code class="function">pthread_cond_wait</code> without aborting
the process.
</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="api.rel_123"></a><code class="constant">12.3</code></h3></div></div></div><p>
Calling a <code class="code">std::bind</code> result as volatile is ill-formed for C++20
and later.
</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="abi.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendix_porting.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="backwards.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ABI Policy and Guidelines </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Backwards Compatibility</td></tr></table></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -524,6 +524,12 @@
</em></span>
</span></dt><dd><p>Avoid using <code class="code">dynamic_cast</code> when it would be
ill-formed.
</p></dd><dt><a id="manual.bugs.dr2487"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2487" target="_top">2487</a>:
<span class="emphasis"><em><code class="code">bind()</code> should be <code class="code">const</code>-overloaded
not cv-overloaded
</em></span>
</span></dt><dd><p>Deprecate volatile-qualified <code class="code">operator()</code>
for C++17, make it ill-formed for C++20.
</p></dd><dt><a id="manual.bugs.dr2499"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2499" target="_top">2499</a>:
<span class="emphasis"><em><code class="code">operator&gt;&gt;(basic_istream&amp;, CharT*)</code> makes it hard to avoid buffer overflows
</em></span>

File diff suppressed because one or more lines are too long

View File

@@ -43,7 +43,7 @@
<a class="link" href="configure.html" title="Configure">Configure</a>),
with the various --enable/--disable choices being translated to
#define/#undef).
</p><p> <acronym class="acronym">ABI</acronym> means that changing from the default value may
</p><p> <acronym class="acronym">ABI</acronym>-changing means that changing from the default value may
mean changing the <acronym class="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
@@ -53,7 +53,8 @@
consistent linkage requires changing the config headers before
building/installing the library.
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="code">_GLIBCXX_USE_DEPRECATED</code></span></dt><dd><p>
Defined by default. Not configurable. ABI-changing. Turning this off
Defined to the value <code class="literal">1</code> 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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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
/**

View File

@@ -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
}

View File

@@ -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()