mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
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:
File diff suppressed because one or more lines are too long
@@ -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"><experimental/source_location></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
@@ -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>>(basic_istream&, CharT*)</code> makes it hard to avoid buffer overflows
|
||||
</em></span>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user