From 50c2df93a6a450228b75901fad7e20cd2e7a8ee7 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 29 Jul 2019 15:27:19 +0100 Subject: [PATCH] PR libstdc++/51333 Define recursive_init_error constructor non-inline The recursive_init_error class is defined in a header, with an inline constructor, but the definition of the vtable and destructor are not exported from the shared library. With -fkeep-inline-functions the constructor gets emitted in user code, and requires the (non-exported) vtable. This fails to link. As far as I can tell, the recursive_init_error class definition was moved into so it could be documented with Doxygen, not for any technical reason. But now it's there (and documented), somebody could be relying on it, by catching that type and possibly performing derived-to-base conversions to the std::exception base class. So the conservative fix is to leave the class definition in the header but make the constructor non-inline. This still allows the type to be caught and still defines its base class. User code can no longer construct objects of that type, but that's not something we need to support. PR libstdc++/51333 * libsupc++/cxxabi.h (__gnu_cxx::recursive_init_error): Do not define constructor inline. * libsupc++/guard_error.cc (__gnu_cxx::recursive_init_error): Define constructor. * testsuite/18_support/51333.cc: New test. From-SVN: r273878 --- libstdc++-v3/ChangeLog | 9 +++++++++ libstdc++-v3/libsupc++/cxxabi.h | 9 +++++---- libstdc++-v3/libsupc++/guard_error.cc | 4 ++-- libstdc++-v3/testsuite/18_support/51333.cc | 22 ++++++++++++++++++++++ 4 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 libstdc++-v3/testsuite/18_support/51333.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 11be89647b8..84fc03b048b 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2019-07-29 Jonathan Wakely + + PR libstdc++/51333 + * libsupc++/cxxabi.h (__gnu_cxx::recursive_init_error): Do not define + constructor inline. + * libsupc++/guard_error.cc (__gnu_cxx::recursive_init_error): Define + constructor. + * testsuite/18_support/51333.cc: New test. + 2019-07-28 Gerald Pfeifer * doc/xml/manual/documentation_hacking.xml: Fix broken reference diff --git a/libstdc++-v3/libsupc++/cxxabi.h b/libstdc++-v3/libsupc++/cxxabi.h index 3562d4c2271..4d9f829ffed 100644 --- a/libstdc++-v3/libsupc++/cxxabi.h +++ b/libstdc++-v3/libsupc++/cxxabi.h @@ -684,8 +684,9 @@ namespace __gnu_cxx * @brief Exception thrown by __cxa_guard_acquire. * @ingroup exceptions * - * 6.7[stmt.dcl]/4: If control re-enters the declaration (recursively) - * while the object is being initialized, the behavior is undefined. + * C++ 2011 6.7 [stmt.dcl]/4: If control re-enters the declaration + * recursively while the variable is being initialized, the behavior + * is undefined. * * Since we already have a library function to handle locking, we might * as well check for this situation and throw an exception. @@ -695,8 +696,8 @@ namespace __gnu_cxx class recursive_init_error: public std::exception { public: - recursive_init_error() throw() { } - virtual ~recursive_init_error() throw (); + recursive_init_error() _GLIBCXX_NOTHROW; + virtual ~recursive_init_error() _GLIBCXX_NOTHROW; }; } #endif // __cplusplus diff --git a/libstdc++-v3/libsupc++/guard_error.cc b/libstdc++-v3/libsupc++/guard_error.cc index 7595c67872a..d7625af4d54 100644 --- a/libstdc++-v3/libsupc++/guard_error.cc +++ b/libstdc++-v3/libsupc++/guard_error.cc @@ -26,6 +26,6 @@ namespace __gnu_cxx { - recursive_init_error::~recursive_init_error() throw() { } + recursive_init_error::recursive_init_error() noexcept { } + recursive_init_error::~recursive_init_error() noexcept { } } - diff --git a/libstdc++-v3/testsuite/18_support/51333.cc b/libstdc++-v3/testsuite/18_support/51333.cc new file mode 100644 index 00000000000..0fb7c338f8b --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/51333.cc @@ -0,0 +1,22 @@ +// 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-options "-fkeep-inline-functions" } +// { dg-do link } + +#include +int main() { } // PR libstdc++/51333