From patchwork Fri May 31 10:37:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1108289 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-502063-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="bFkzcFGD"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45Fgr73mpXz9sCJ for ; Fri, 31 May 2019 20:37:27 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=sbretL/rL1xVwl9EXQC7pGDMexIVA2Irqa8HPHnhQzu0XRvzVeMwq JFV/WIIZMISQdzjCJRnI/2mDaCr3tblX1Hh8SQ7QdI5dnQedAHcCwP4PvxF2e9Mb c2ipriDWjrud0Z2V3ZS3mRhhhA0PfuwNZx0FoNlPm9y3SM9Y06LZfs= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=CXfNElH/tDQUX3QlP/0MXMzq5/M=; b=bFkzcFGDdhCkF/bUGUs0 nafMQLYLDKH73wImawn4qlJYL5XfCZOGIArxoXmtIMeHEo0miz/9EZr9QQ5SGFSb K9GBkVJO7/pRrnzzH6xJLqZH5YgtXcqUgmzFsQWcdq9LqH8O6kM0hp6B0YiNSv5J AxEfn4ewOz9wCuEvPocNuo4= Received: (qmail 125960 invoked by alias); 31 May 2019 10:37:09 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 125904 invoked by uid 89); 31 May 2019 10:37:08 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-15.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=GPL, gpl X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 31 May 2019 10:37:05 +0000 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6772D307D98A; Fri, 31 May 2019 10:37:04 +0000 (UTC) Received: from localhost (unknown [10.33.36.135]) by smtp.corp.redhat.com (Postfix) with ESMTP id 15F385D6A6; Fri, 31 May 2019 10:37:03 +0000 (UTC) Date: Fri, 31 May 2019 11:37:03 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] PR libstdc++/90682 allow set_terminate(0) and set_unexpected(0) Message-ID: <20190531103703.GA28887@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.11.3 (2019-02-01) 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. 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. Tested x86_64-linux, committed to trunk. commit 4a0eb6b39bc2668baebe17f0120187b22f726851 Author: Jonathan Wakely Date: Fri May 31 00:26:44 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. 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. diff --git a/libstdc++-v3/libsupc++/eh_term_handler.cc b/libstdc++-v3/libsupc++/eh_term_handler.cc index 6a368c0699e..4b330bc9177 100644 --- a/libstdc++-v3/libsupc++/eh_term_handler.cc +++ b/libstdc++-v3/libsupc++/eh_term_handler.cc @@ -24,21 +24,8 @@ #include #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 -/* 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 00000000000..e4774bdf9c5 --- /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 +// . + +#include + +/* 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 +# 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 6acae0593ac..d5f24ea1000 100644 --- a/libstdc++-v3/libsupc++/eh_terminate.cc +++ b/libstdc++-v3/libsupc++/eh_terminate.cc @@ -26,6 +26,7 @@ #include "exception" #include #include "unwind-cxx.h" +#include "eh_term_handler.h" #include #include @@ -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 00000000000..632b9f1974a --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/set_terminate.cc @@ -0,0 +1,56 @@ +// 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 +// . + +// { dg-do run } + +#include +#include + +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 00000000000..dac44e616cd --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/set_unexpected.cc @@ -0,0 +1,56 @@ +// 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 +// . + +// { dg-do run { target { c++98_only || { c++11_only || c++14_only } } } } + +#include +#include + +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(); +}