libstdc++: Deprecate std::unexpected and handler functions

These functions have been deprecated since C++11, and were removed in
C++17. The proposal P0323 wants to reuse the name std::unexpected for a
class template, so we will need to stop defining the current function
for C++23 anyway.

This marks them as deprecated for C++11 and up, to warn users they won't
continue to be available. It disables them for C++17 and up, unless the
_GLIBCXX_USE_DEPRECATED macro is defined.

The <unwind-cxx.h> header uses std::unexpected_handler in the public
API, but since that type is the same as std::terminate_handler we can
just use that instead, to avoid warnings about it being deprecated.

libstdc++-v3/ChangeLog:

	* doc/xml/manual/evolution.xml: Document deprecations.
	* doc/html/*: Regenerate.
	* libsupc++/exception (unexpected_handler, unexpected)
	(get_unexpected, set_unexpected): Add deprecated attribute.
	Do not define without _GLIBCXX_USE_DEPRECATED for C++17 and up.
	* libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Disable
	deprecated warnings.
	* libsupc++/eh_ptr.cc (std::rethrow_exception): Likewise.
	* libsupc++/eh_terminate.cc: Likewise.
	* libsupc++/eh_throw.cc (__cxa_init_primary_exception):
	Likewise.
	* libsupc++/unwind-cxx.h (struct __cxa_exception): Use
	terminate_handler instead of unexpected_handler.
	(struct __cxa_dependent_exception): Likewise.
	(__unexpected): Likewise.
	* testsuite/18_support/headers/exception/synopsis.cc: Add
	dg-warning for deprecated warning.
	* testsuite/18_support/exception_ptr/60612-unexpected.cc:
	Disable deprecated warnings.
	* testsuite/18_support/set_unexpected.cc: Likewise.
	* testsuite/18_support/unexpected_handler.cc: Likewise.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp0x/lambda/lambda-eh2.C: Add dg-warning for new
	deprecation warnings.
	* g++.dg/cpp0x/noexcept06.C: Likewise.
	* g++.dg/cpp0x/noexcept07.C: Likewise.
	* g++.dg/eh/forced3.C: Likewise.
	* g++.dg/eh/unexpected1.C: Likewise.
	* g++.old-deja/g++.eh/spec1.C: Likewise.
	* g++.old-deja/g++.eh/spec2.C: Likewise.
	* g++.old-deja/g++.eh/spec3.C: Likewise.
	* g++.old-deja/g++.eh/spec4.C: Likewise.
	* g++.old-deja/g++.mike/eh33.C: Likewise.
	* g++.old-deja/g++.mike/eh34.C: Likewise.
	* g++.old-deja/g++.mike/eh50.C: Likewise.
	* g++.old-deja/g++.mike/eh51.C: Likewise.
This commit is contained in:
Jonathan Wakely 2021-09-29 21:18:42 +01:00
parent 79fe28d2c4
commit f4130a3eb5
25 changed files with 65 additions and 28 deletions

View File

@ -7,7 +7,7 @@
int main( void )
{
std::set_unexpected( []{ throw 0; } );
std::set_unexpected( []{ throw 0; } ); // { dg-warning "deprecated" }
try
{
[]() throw( int ) { throw nullptr; }(); // { dg-warning "deprecated" }

View File

@ -23,7 +23,7 @@ void f() noexcept
int main()
{
std::set_unexpected (my_unexpected);
std::set_unexpected (my_unexpected); // { dg-warning "deprecated" }
std::set_terminate (my_terminate);
f();
return 1;

View File

@ -18,7 +18,7 @@ void f() throw()
int main()
{
std::set_unexpected (my_unexpected);
std::set_unexpected (my_unexpected); // { dg-warning "deprecated" }
f();
return 1;
}

View File

@ -53,7 +53,7 @@ doit () throw()
int main()
{
std::set_unexpected (handle_unexpected);
std::set_unexpected (handle_unexpected); // { dg-warning "deprecated" "" { target c++11 } }
doit ();
abort ();
}

View File

@ -30,7 +30,7 @@ doit () throw (Two) // { dg-warning "deprecated" "" { target { c++11 } } }
int main ()
{
std::set_unexpected (handle_unexpected);
std::set_unexpected (handle_unexpected); // { dg-warning "deprecated" "" { target { c++11 } } }
try
{

View File

@ -17,7 +17,7 @@ f () throw (char, int, std::bad_exception) // { dg-warning "deprecated" "" { tar
int main ()
{
std::set_terminate (my_term);
std::set_unexpected (my_unexp);
std::set_unexpected (my_unexp); // { dg-warning "deprecated" "" { target c++11 } }
try
{

View File

@ -17,7 +17,7 @@ f () throw (int, std::bad_exception) // { dg-warning "deprecated" "" { target c+
int main ()
{
std::set_terminate (my_term);
std::set_unexpected (my_unexp);
std::set_unexpected (my_unexp); // { dg-warning "deprecated" "" { target c++11 } }
try
{

View File

@ -17,7 +17,7 @@ f () throw (std::bad_exception) // { dg-warning "deprecated" "" { target c++11
int main ()
{
std::set_terminate (my_term);
std::set_unexpected (my_unexp);
std::set_unexpected (my_unexp); // { dg-warning "deprecated" "" { target c++11 } }
try
{

View File

@ -17,7 +17,7 @@ f () throw (short) // { dg-warning "deprecated" "" { target c++11 } }
int main ()
{
std::set_terminate (my_term);
std::set_unexpected (my_unexp);
std::set_unexpected (my_unexp); // { dg-warning "deprecated" "" { target c++11 } }
try
{

View File

@ -11,7 +11,7 @@ void my_unexpected() {
void foo() throw (int) { throw "Hi"; } // { dg-warning "deprecated" "" { target c++11 } }
int main() {
std::set_unexpected (my_unexpected);
std::set_unexpected (my_unexpected); // { dg-warning "deprecated" "" { target c++11 } }
try {
foo();
} catch (int i) {

View File

@ -11,7 +11,7 @@ void my_unexpected() {
void foo() throw () { throw "Hi"; }
int main() {
std::set_unexpected (my_unexpected);
std::set_unexpected (my_unexpected); // { dg-warning "deprecated" "" { target c++11 } }
foo();
return 1;
}

View File

@ -12,7 +12,7 @@ template <class T> void foo(T) throw (int) { throw "Hi"; } // { dg-warning "depr
int
main() {
std::set_unexpected (my_unexpected);
std::set_unexpected (my_unexpected); // { dg-warning "deprecated" "" { target c++11 } }
try {
foo(1);
} catch (int i) {

View File

@ -12,7 +12,7 @@ template <class T> void foo(T) throw (T) { throw "Hi"; } // { dg-warning "deprec
int
main() {
std::set_unexpected (my_unexpected);
std::set_unexpected (my_unexpected); // { dg-warning "deprecated" "" { target c++11 } }
try {
foo(1);
} catch (int i) {

View File

@ -440,4 +440,8 @@ now defaults to zero.
The <code class="function">std::random_shuffle</code> algorithms are deprecated
for C++14 and later. The C++11 <code class="function">std::shuffle</code> algorithm
can be used instead.
</p><p>
The <code class="function">std::unexpected</code> function and related typedef and
accessors for the unexpected handler are deprecated for C++11 and later.
Dynamic exception specifications should be replaced with <code class="code">noexcept</code>.
</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>

View File

@ -1027,6 +1027,12 @@ for C++14 and later. The C++11 <function>std::shuffle</function> algorithm
can be used instead.
</para>
<para>
The <function>std::unexpected</function> function and related typedef and
accessors for the unexpected handler are deprecated for C++11 and later.
Dynamic exception specifications should be replaced with <code>noexcept</code>.
</para>
</section>
</section>

View File

@ -673,10 +673,13 @@ PERSONALITY_FUNCTION (int version,
std::terminate ();
else if (handler_switch_value < 0)
{
__try
{ std::unexpected (); }
__catch(...)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
__try
{ std::unexpected (); }
__catch(...)
{ std::terminate (); }
#pragma GCC diagnostic pop
}
}
else

View File

@ -198,7 +198,10 @@ std::rethrow_exception(std::exception_ptr ep)
dep->primaryException = obj;
__gnu_cxx::__eh_atomic_inc (&eh->referenceCount);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
dep->unexpectedHandler = get_unexpected ();
#pragma GCC diagnostic pop
dep->terminateHandler = get_terminate ();
__GXX_INIT_DEPENDENT_EXCEPTION_CLASS(dep->unwindHeader.exception_class);
dep->unwindHeader.exception_cleanup = __gxx_dependent_exception_cleanup;

View File

@ -58,6 +58,7 @@ std::terminate () throw()
__cxxabiv1::__terminate (get_terminate ());
}
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
void
__cxxabiv1::__unexpected (std::unexpected_handler handler)
{

View File

@ -63,7 +63,10 @@ _GLIBCXX_NOTHROW
header->referenceCount = 0;
header->exc.exceptionType = tinfo;
header->exc.exceptionDestructor = dest;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
header->exc.unexpectedHandler = std::get_unexpected ();
#pragma GCC diagnostic pop
header->exc.terminateHandler = std::get_terminate ();
__GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->exc.unwindHeader.exception_class);
header->exc.unwindHeader.exception_cleanup = __gxx_exception_cleanup;

View File

@ -67,9 +67,6 @@ namespace std
/// If you write a replacement %terminate handler, it must be of this type.
typedef void (*terminate_handler) ();
/// If you write a replacement %unexpected handler, it must be of this type.
typedef void (*unexpected_handler) ();
/// Takes a new handler function as an argument, returns the old function.
terminate_handler set_terminate(terminate_handler) _GLIBCXX_USE_NOEXCEPT;
@ -82,17 +79,35 @@ namespace std
* abandoned for any reason. It can also be called by the user. */
void terminate() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__noreturn__));
/// Takes a new handler function as an argument, returns the old function.
#if __cplusplus < 201703L || _GLIBCXX_USE_DEPRECATED
/// If you write a replacement %unexpected handler, it must be of this type.
typedef void (*_GLIBCXX11_DEPRECATED unexpected_handler) ();
/** Takes a new handler function as an argument, returns the old function.
*
* @deprecated Removed from the C++ standard in C++17
*/
_GLIBCXX11_DEPRECATED
unexpected_handler set_unexpected(unexpected_handler) _GLIBCXX_USE_NOEXCEPT;
#if __cplusplus >= 201103L
/// Return the current unexpected handler.
/** Return the current unexpected handler.
*
* @since C++11
* @deprecated Removed from the C++ standard in C++17
*/
_GLIBCXX11_DEPRECATED
unexpected_handler get_unexpected() noexcept;
#endif
/** The runtime will call this function if an %exception is thrown which
* violates the function's %exception specification. */
* violates the function's %exception specification.
*
* @deprecated Removed from the C++ standard in C++17
*/
_GLIBCXX11_DEPRECATED
void unexpected() __attribute__ ((__noreturn__));
#endif
/** [18.6.4]/1: 'Returns true after completing evaluation of a
* throw-expression until either completing initialization of the

View File

@ -67,7 +67,7 @@ struct __cxa_exception
// The C++ standard has entertaining rules wrt calling set_terminate
// and set_unexpected in the middle of the exception cleanup process.
std::unexpected_handler unexpectedHandler;
std::terminate_handler unexpectedHandler;
std::terminate_handler terminateHandler;
// The caught exception stack threads through here.
@ -121,7 +121,7 @@ struct __cxa_dependent_exception
// The C++ standard has entertaining rules wrt calling set_terminate
// and set_unexpected in the middle of the exception cleanup process.
std::unexpected_handler unexpectedHandler;
std::terminate_handler unexpectedHandler;
std::terminate_handler terminateHandler;
// The caught exception stack threads through here.
@ -191,12 +191,12 @@ extern "C" void __cxa_tm_cleanup (void *, void *, unsigned int) throw();
// so inconsiderate as to return.
extern void __terminate(std::terminate_handler) throw ()
__attribute__((__noreturn__));
extern void __unexpected(std::unexpected_handler)
extern void __unexpected(std::terminate_handler)
__attribute__((__noreturn__));
// The current installed user handlers.
extern std::terminate_handler __terminate_handler;
extern std::unexpected_handler __unexpected_handler;
extern std::terminate_handler __unexpected_handler;
// These are explicitly GNU C++ specific.

View File

@ -1,3 +1,4 @@
// { dg-options "-Wno-deprecated-declarations" }
// { dg-do run { target { c++11_only || c++14_only } } }
// Copyright (C) 2014-2021 Free Software Foundation, Inc.

View File

@ -24,7 +24,7 @@ namespace std {
class bad_exception;
typedef void (*unexpected_handler)();
unexpected_handler set_unexpected(unexpected_handler f ) throw();
unexpected_handler set_unexpected(unexpected_handler f ) throw(); // { dg-warning "deprecated" { target c++11 } }
unexpected_handler get_unexpected() noexcept;
void unexpected();

View File

@ -15,7 +15,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
// { dg-options "-std=gnu++11 -Wno-deprecated-declarations" }
// { dg-do run { target { c++11_only || c++14_only } } }
#include <exception>

View File

@ -15,6 +15,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-Wno-deprecated-declarations" }
// { dg-do run { target c++11 } }
// D.11 Violating exception-specifications