2019-05-31 Jonathan Wakely <jwakely@redhat.com>
+ PR libstdc++/90682
+ * libsupc++/eh_term_handler.cc: Include eh_term_handler.h to get
+ definition of _GLIBCXX_DEFAULT_TERM_HANDLER.
+ * libsupc++/eh_term_handler.h: New header defining
+ _GLIBCXX_DEFAULT_TERM_HANDLER.
+ * libsupc++/eh_terminate.cc: Include eh_term_handler.h.
+ (set_terminate): Restore default handler when argument is null.
+ (set_unexpected): Likewise.
+ * testsuite/18_support/set_terminate.cc: New test.
+ * testsuite/18_support/set_unexpected.cc: New test.
+
* include/backward/hashtable.h (size_t, ptrdiff_t)
(forward_iterator_tag, input_iterator_tag, _Construct, _Destroy)
(distance, vector, pair, __iterator_category): Remove
#include <bits/c++config.h>
#include "unwind-cxx.h"
+#include "eh_term_handler.h"
-/* We default to the talkative, informative handler in a normal hosted
- library. This pulls in the demangler, the dyn-string utilities, and
- elements of the I/O library. For a low-memory environment, you can return
- to the earlier "silent death" handler by configuring GCC with
- --disable-libstdcxx-verbose and rebuilding the library.
- In a freestanding environment, we default to this latter approach. */
-
-#if _GLIBCXX_HOSTED && _GLIBCXX_VERBOSE && __cpp_exceptions
/* The current installed user handler. */
std::terminate_handler __cxxabiv1::__terminate_handler =
- __gnu_cxx::__verbose_terminate_handler;
-#else
-# include <cstdlib>
-/* The current installed user handler. */
-std::terminate_handler __cxxabiv1::__terminate_handler = std::abort;
-#endif
-
+ _GLIBCXX_DEFAULT_TERM_HANDLER;
--- /dev/null
+// -*- C++ -*- default std::terminate handler
+// Copyright (C) 2002-2019 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// GCC is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// GCC is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+#include <bits/c++config.h>
+
+/* We default to the talkative, informative handler in a normal hosted
+ library. This pulls in the demangler, the dyn-string utilities, and
+ elements of the I/O library. For a low-memory environment, you can return
+ to the earlier "silent death" handler by configuring GCC with
+ --disable-libstdcxx-verbose and rebuilding the library.
+ In a freestanding environment, we default to this latter approach. */
+
+#if _GLIBCXX_HOSTED && _GLIBCXX_VERBOSE && __cpp_exceptions
+# define _GLIBCXX_DEFAULT_TERM_HANDLER __gnu_cxx::__verbose_terminate_handler
+#else
+# include <cstdlib>
+# define _GLIBCXX_DEFAULT_TERM_HANDLER std::abort
+#endif
#include "exception"
#include <cstdlib>
#include "unwind-cxx.h"
+#include "eh_term_handler.h"
#include <bits/exception_defines.h>
#include <bits/atomic_lockfree_defines.h>
std::terminate_handler
std::set_terminate (std::terminate_handler func) throw()
{
+ if (!func)
+ func = _GLIBCXX_DEFAULT_TERM_HANDLER;
+
std::terminate_handler old;
#if ATOMIC_POINTER_LOCK_FREE > 1
__atomic_exchange (&__terminate_handler, &func, &old, __ATOMIC_ACQ_REL);
std::unexpected_handler
std::set_unexpected (std::unexpected_handler func) throw()
{
+ if (!func)
+ func = std::terminate;
+
std::unexpected_handler old;
#if ATOMIC_POINTER_LOCK_FREE > 1
__atomic_exchange (&__unexpected_handler, &func, &old, __ATOMIC_ACQ_REL);
--- /dev/null
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run }
+
+#include <exception>
+#include <testsuite_hooks.h>
+
+void term_handler() { __builtin_abort(); }
+
+void
+test01()
+{
+ const std::terminate_handler orig = std::get_terminate();
+ VERIFY( orig != 0 ); // GNU-specific behaviour
+
+ std::terminate_handler prev = std::set_terminate(term_handler);
+ VERIFY( std::get_terminate() == term_handler );
+ VERIFY( prev == orig );
+
+ prev = std::set_terminate(orig);
+ VERIFY( std::get_terminate() == orig );
+ VERIFY( prev == term_handler );
+}
+
+void
+test02()
+{
+ // PR libstdc++/90682
+ std::set_terminate(0); // Undefined in C++98, unspecified in C++11 and later
+ const std::terminate_handler dfault = std::get_terminate();
+ VERIFY( dfault != 0 ); // GNU-specific behaviour
+ const std::terminate_handler prev = std::set_terminate(0);
+ VERIFY( prev == dfault );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
--- /dev/null
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target { c++98_only || { c++11_only || c++14_only } } } }
+
+#include <exception>
+#include <testsuite_hooks.h>
+
+void unex_handler() { __builtin_abort(); }
+
+void
+test01()
+{
+ const std::unexpected_handler orig = std::get_unexpected();
+ VERIFY( orig == std::terminate ); // GNU-specific behaviour
+
+ std::unexpected_handler prev = std::set_unexpected(unex_handler);
+ VERIFY( std::get_unexpected() == unex_handler );
+ VERIFY( prev == orig );
+
+ prev = std::set_unexpected(orig);
+ VERIFY( std::get_unexpected() == orig );
+ VERIFY( prev == unex_handler );
+}
+
+void
+test02()
+{
+ // PR libstdc++/90682
+ std::set_unexpected(0); // Undefined in C++98, unspecified in C++11 and C++14
+ const std::unexpected_handler dfault = std::get_unexpected();
+ VERIFY( dfault == std::terminate ); // GNU-specific behaviour
+ const std::unexpected_handler prev = std::set_unexpected(0);
+ VERIFY( prev == dfault );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}