[gcc(refs/vendors/ibm/heads/gcc-9-branch)] PR libstdc++/90682 allow set_terminate(0) and set_unexpected(0)

Peter Bergner bergner@gcc.gnu.org
Tue Feb 4 22:03:00 GMT 2020


https://gcc.gnu.org/g:14fe05d883b4272fe326a665ad589df7ac800e72

commit 14fe05d883b4272fe326a665ad589df7ac800e72
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Oct 24 13:55:27 2019 +0100

    PR libstdc++/90682 allow set_terminate(0) and set_unexpected(0)
    
    Make these functions restore the default handlers when passed a null
    pointer. This is consistent with std::pmr::set_default_resource(0), and
    also matches the current behaviour of libc++.
    
    In order to avoid duplicating the preprocessor condition from
    eh_term_handler.cc more that into a new eh_term_handler.h header and
    define a macro that can be used in both eh_term_handler.cc and
    eh_terminate.cc.
    
    Backport from mainline
    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.
    
    From-SVN: r277393

Diff:
---
 libstdc++-v3/ChangeLog                             | 14 ++++++
 libstdc++-v3/libsupc++/eh_term_handler.cc          | 17 +------
 libstdc++-v3/libsupc++/eh_term_handler.h           | 39 +++++++++++++++
 libstdc++-v3/libsupc++/eh_terminate.cc             |  7 +++
 libstdc++-v3/testsuite/18_support/set_terminate.cc | 57 ++++++++++++++++++++++
 .../testsuite/18_support/set_unexpected.cc         | 57 ++++++++++++++++++++++
 6 files changed, 176 insertions(+), 15 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index c899cec..2cc882f 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,6 +1,20 @@
 2019-10-24  Jonathan Wakely  <jwakely@redhat.com>
 
 	Backport from mainline
+	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.
+
+	Backport from mainline
 	2019-05-01  Jonathan Wakely  <jwakely@redhat.com>
 
 	PR libstdc++/61761
diff --git a/libstdc++-v3/libsupc++/eh_term_handler.cc b/libstdc++-v3/libsupc++/eh_term_handler.cc
index 6a368c0..4b330bc 100644
--- a/libstdc++-v3/libsupc++/eh_term_handler.cc
+++ b/libstdc++-v3/libsupc++/eh_term_handler.cc
@@ -24,21 +24,8 @@
 
 #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;
diff --git a/libstdc++-v3/libsupc++/eh_term_handler.h b/libstdc++-v3/libsupc++/eh_term_handler.h
new file mode 100644
index 0000000..e4774bd
--- /dev/null
+++ b/libstdc++-v3/libsupc++/eh_term_handler.h
@@ -0,0 +1,39 @@
+// -*- 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
diff --git a/libstdc++-v3/libsupc++/eh_terminate.cc b/libstdc++-v3/libsupc++/eh_terminate.cc
index 6acae05..d5f24ea 100644
--- a/libstdc++-v3/libsupc++/eh_terminate.cc
+++ b/libstdc++-v3/libsupc++/eh_terminate.cc
@@ -26,6 +26,7 @@
 #include "exception"
 #include <cstdlib>
 #include "unwind-cxx.h"
+#include "eh_term_handler.h"
 #include <bits/exception_defines.h>
 #include <bits/atomic_lockfree_defines.h>
 
@@ -73,6 +74,9 @@ std::unexpected ()
 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);
@@ -100,6 +104,9 @@ std::get_terminate () noexcept
 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);
diff --git a/libstdc++-v3/testsuite/18_support/set_terminate.cc b/libstdc++-v3/testsuite/18_support/set_terminate.cc
new file mode 100644
index 0000000..81f182a
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/set_terminate.cc
@@ -0,0 +1,57 @@
+// 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-options "-std=gnu++11" }
+// { 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();
+}
diff --git a/libstdc++-v3/testsuite/18_support/set_unexpected.cc b/libstdc++-v3/testsuite/18_support/set_unexpected.cc
new file mode 100644
index 0000000..7c3f3d4
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/set_unexpected.cc
@@ -0,0 +1,57 @@
+// 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-options "-std=gnu++11" }
+// { dg-do run { target { 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();
+}



More information about the Libstdc++-cvs mailing list