mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 03:47:02 -05:00
libstdc++: Use gnu_inline attribute on constexpr exception methods [PR123183]
As mentioned in https://gcc.gnu.org/pipermail/gcc-patches/2026-January/704712.html in the gnu::constexpr_only thread, gnu::gnu_inline attribute actually seems to work for most of what we need for C++26 constexpr exceptions (i.e. when we want out of line bodies for C++ < 26 and need to use constexpr for C++26, yet don't want for reasons mentioned in those two PRs the bodies of those constexpr methods to be emitted inline). Unfortunately clang++ doesn't handle it 100% properly and requires the redundant inline keyword to make it work (even when the methods are constexpr and thus implicilty inline), g++ doesn't require that, so the patch adds also the redundant inline keywords and not just the [[__gnu__::__gnu_inline__]] attribute. This way if something wants to inline those functions it can, but if their address is taken, we just rely on libstdc++.{so,a} to provide those (which it does as before because those TUs are compiled with older -std= modes). The earlier r16-6477-gd5743234731 commit made sure gnu::gnu_inline constexpr virtual methods can be key methods, so vtables and rtti can be emitted only in the TU defining non-gnu_inline versions of those. 2026-01-07 Jakub Jelinek <jakub@redhat.com> PR libstdc++/123183 PR libstdc++/123326 * libsupc++/exception (std::bad_exception::~bad_exception(), std::bad_exception::what()): Add inline keyword and [[__gnu__::__gnu_inline__]] attribute to the C++26 constexpr exceptions definitions. * libsupc++/exception.h (std::exception::~exception(), std::exception::what()): Likewise. * libsupc++/exception_ptr.h (std::exception_ptr::exception_ptr(void*)): Likewise. * libsupc++/nested_exception.h (std::nested_exception::~nested_exception()): Likewise. * libsupc++/typeinfo (std::bad_cast::~bad_cast(), std::bad_cast::what(), std::bad_typeid::~bad_typeid(), std::bad_typeid::what()): Likewise. * include/bits/new_except.h (std::bad_alloc::~bad_alloc(), std::bad_alloc::what(), std::bad_array_new_length::~bad_array_new_length(), std::bad_array_new_length::what()): Likewise. * include/bits/stdexcept_except.h (std::logic_error::logic_error(const string&), std::logic_error::logic_error(const char*), std::logic_error::~logic_error(), std::logic_error::what(), std::domain_error::domain_error(const string&), std::domain_error::domain_error(const char*), std::invalid_argument::invalid_argument(const string&), std::invalid_argument::invalid_argument(const char*), std::length_error::length_error(const string&), std::length_error::length_error(const char*), std::out_of_range::out_of_range(const string&), std::out_of_range::out_of_range(const char*), std::runtime_error::runtime_error(const string&), std::runtime_error::runtime_error(const char*), std::runtime_error::~runtime_error(), std::runtime_error::what(), std::overflow_error::overflow_error(const string&), std::overflow_error::overflow_error(const char*), std::overflow_error::~overflow_error(), std::underflow_error::underflow_error(const string&), std::underflow_error::underflow_error(const char*), std::underflow_error::~underflow_error()): Likewise. (std::domain_error::~domain_error(), std::invalid_argument::~invalid_argument(), std::length_error::~length_error(), std::out_of_range::~out_of_range()): Likewise. Also change _GLIBCXX_NOTHROW to noexcept on those definitions.
This commit is contained in:
committed by
Jakub Jelinek
parent
c0a6fda04a
commit
f8c32184b8
@@ -62,9 +62,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 202400L
|
||||
constexpr virtual ~bad_alloc() noexcept {}
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~bad_alloc() noexcept {}
|
||||
|
||||
constexpr virtual const char* what() const noexcept
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual const char* what() const noexcept
|
||||
{
|
||||
return "std::bad_alloc";
|
||||
}
|
||||
@@ -85,9 +87,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
_GLIBCXX26_CONSTEXPR bad_array_new_length() throw() { }
|
||||
|
||||
#if __cplusplus >= 202400L
|
||||
constexpr virtual ~bad_array_new_length() noexcept {}
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~bad_array_new_length() noexcept {}
|
||||
|
||||
constexpr virtual const char* what() const noexcept
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual const char* what() const noexcept
|
||||
{
|
||||
return "std::bad_array_new_length";
|
||||
}
|
||||
|
||||
@@ -258,11 +258,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
public:
|
||||
#if __cpp_lib_constexpr_exceptions >= 202502L
|
||||
constexpr explicit
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit
|
||||
logic_error(const string& __arg) _GLIBCXX_TXN_SAFE
|
||||
: _M_msg(__arg) {}
|
||||
|
||||
constexpr explicit
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit
|
||||
logic_error(const char* __arg) _GLIBCXX_TXN_SAFE
|
||||
: _M_msg(__arg) {}
|
||||
|
||||
@@ -271,9 +273,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
constexpr logic_error(const logic_error&) noexcept = default;
|
||||
constexpr logic_error& operator=(const logic_error&) noexcept = default;
|
||||
|
||||
constexpr virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN noexcept { }
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN noexcept { }
|
||||
|
||||
constexpr virtual const char*
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual const char*
|
||||
what() const _GLIBCXX_TXN_SAFE_DYN noexcept
|
||||
{
|
||||
return _M_msg.c_str();
|
||||
@@ -319,15 +323,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{
|
||||
public:
|
||||
#if __cpp_lib_constexpr_exceptions >= 202502L
|
||||
constexpr explicit domain_error(const string& __arg) _GLIBCXX_TXN_SAFE
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit domain_error(const string& __arg)
|
||||
_GLIBCXX_TXN_SAFE
|
||||
: logic_error(__arg) { }
|
||||
constexpr explicit domain_error(const char* __arg) _GLIBCXX_TXN_SAFE
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit domain_error(const char* __arg) _GLIBCXX_TXN_SAFE
|
||||
: logic_error(__arg) { }
|
||||
constexpr domain_error(const domain_error&) = default;
|
||||
constexpr domain_error& operator=(const domain_error&) = default;
|
||||
constexpr domain_error(domain_error&&) = default;
|
||||
constexpr domain_error& operator=(domain_error&&) = default;
|
||||
constexpr virtual ~domain_error() _GLIBCXX_NOTHROW { }
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~domain_error() noexcept { }
|
||||
#else
|
||||
explicit domain_error(const string& __arg) _GLIBCXX_TXN_SAFE;
|
||||
#if __cplusplus >= 201103L
|
||||
@@ -346,15 +354,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{
|
||||
public:
|
||||
#if __cpp_lib_constexpr_exceptions >= 202502L
|
||||
constexpr explicit invalid_argument(const string& __arg) _GLIBCXX_TXN_SAFE
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit invalid_argument(const string& __arg)
|
||||
_GLIBCXX_TXN_SAFE
|
||||
: logic_error(__arg) { }
|
||||
constexpr explicit invalid_argument(const char* __arg) _GLIBCXX_TXN_SAFE
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit invalid_argument(const char* __arg)
|
||||
_GLIBCXX_TXN_SAFE
|
||||
: logic_error(__arg) { }
|
||||
constexpr invalid_argument(const invalid_argument&) = default;
|
||||
constexpr invalid_argument& operator=(const invalid_argument&) = default;
|
||||
constexpr invalid_argument(invalid_argument&&) = default;
|
||||
constexpr invalid_argument& operator=(invalid_argument&&) = default;
|
||||
constexpr virtual ~invalid_argument() _GLIBCXX_NOTHROW { }
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~invalid_argument() noexcept { }
|
||||
#else
|
||||
explicit invalid_argument(const string& __arg) _GLIBCXX_TXN_SAFE;
|
||||
#if __cplusplus >= 201103L
|
||||
@@ -374,15 +387,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{
|
||||
public:
|
||||
#if __cpp_lib_constexpr_exceptions >= 202502L
|
||||
constexpr explicit length_error(const string& __arg) _GLIBCXX_TXN_SAFE
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit length_error(const string& __arg)
|
||||
_GLIBCXX_TXN_SAFE
|
||||
: logic_error(__arg) { }
|
||||
constexpr explicit length_error(const char* __arg) _GLIBCXX_TXN_SAFE
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit length_error(const char* __arg) _GLIBCXX_TXN_SAFE
|
||||
: logic_error(__arg) { }
|
||||
constexpr length_error(const length_error&) = default;
|
||||
constexpr length_error& operator=(const length_error&) = default;
|
||||
constexpr length_error(length_error&&) = default;
|
||||
constexpr length_error& operator=(length_error&&) = default;
|
||||
constexpr virtual ~length_error() _GLIBCXX_NOTHROW { }
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~length_error() noexcept { }
|
||||
#else
|
||||
explicit length_error(const string& __arg) _GLIBCXX_TXN_SAFE;
|
||||
#if __cplusplus >= 201103L
|
||||
@@ -402,15 +419,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{
|
||||
public:
|
||||
#if __cpp_lib_constexpr_exceptions >= 202502L
|
||||
constexpr explicit out_of_range(const string& __arg) _GLIBCXX_TXN_SAFE
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit out_of_range(const string& __arg)
|
||||
_GLIBCXX_TXN_SAFE
|
||||
: logic_error(__arg) { }
|
||||
constexpr explicit out_of_range(const char* __arg) _GLIBCXX_TXN_SAFE
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit out_of_range(const char* __arg) _GLIBCXX_TXN_SAFE
|
||||
: logic_error(__arg) { }
|
||||
constexpr out_of_range(const out_of_range&) = default;
|
||||
constexpr out_of_range& operator=(const out_of_range&) = default;
|
||||
constexpr out_of_range(out_of_range&&) = default;
|
||||
constexpr out_of_range& operator=(out_of_range&&) = default;
|
||||
constexpr virtual ~out_of_range() _GLIBCXX_NOTHROW { }
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~out_of_range() noexcept { }
|
||||
#else
|
||||
explicit out_of_range(const string& __arg) _GLIBCXX_TXN_SAFE;
|
||||
#if __cplusplus >= 201103L
|
||||
@@ -435,11 +456,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
public:
|
||||
#if __cpp_lib_constexpr_exceptions >= 202502L
|
||||
constexpr explicit
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit
|
||||
runtime_error(const string& __arg) _GLIBCXX_TXN_SAFE
|
||||
: _M_msg(__arg) {}
|
||||
|
||||
constexpr explicit
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit
|
||||
runtime_error(const char* __arg) _GLIBCXX_TXN_SAFE
|
||||
: _M_msg(__arg) {}
|
||||
|
||||
@@ -448,9 +471,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
constexpr runtime_error(const runtime_error&) noexcept = default;
|
||||
runtime_error& operator=(const runtime_error&) noexcept = default;
|
||||
|
||||
constexpr virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN noexcept { }
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN noexcept
|
||||
{}
|
||||
|
||||
constexpr virtual const char*
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual const char*
|
||||
what() const _GLIBCXX_TXN_SAFE_DYN noexcept
|
||||
{
|
||||
return _M_msg.c_str();
|
||||
@@ -495,15 +521,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{
|
||||
public:
|
||||
#if __cpp_lib_constexpr_exceptions >= 202502L
|
||||
constexpr explicit overflow_error(const string& __arg) _GLIBCXX_TXN_SAFE
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit overflow_error(const string& __arg)
|
||||
_GLIBCXX_TXN_SAFE
|
||||
: runtime_error(__arg) { }
|
||||
constexpr explicit overflow_error(const char* __arg) _GLIBCXX_TXN_SAFE
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit overflow_error(const char* __arg)
|
||||
_GLIBCXX_TXN_SAFE
|
||||
: runtime_error(__arg) { }
|
||||
constexpr overflow_error(const overflow_error&) = default;
|
||||
constexpr overflow_error& operator=(const overflow_error&) = default;
|
||||
constexpr overflow_error(overflow_error&&) = default;
|
||||
constexpr overflow_error& operator=(overflow_error&&) = default;
|
||||
constexpr virtual ~overflow_error() noexcept { }
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~overflow_error() noexcept { }
|
||||
#else
|
||||
explicit overflow_error(const string& __arg) _GLIBCXX_TXN_SAFE;
|
||||
#if __cplusplus >= 201103L
|
||||
@@ -522,15 +553,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{
|
||||
public:
|
||||
#if __cpp_lib_constexpr_exceptions >= 202502L
|
||||
constexpr explicit underflow_error(const string& __arg) _GLIBCXX_TXN_SAFE
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit underflow_error(const string& __arg)
|
||||
_GLIBCXX_TXN_SAFE
|
||||
: runtime_error(__arg) { }
|
||||
constexpr explicit underflow_error(const char* __arg) _GLIBCXX_TXN_SAFE
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit underflow_error(const char* __arg)
|
||||
_GLIBCXX_TXN_SAFE
|
||||
: runtime_error(__arg) { }
|
||||
constexpr underflow_error(const underflow_error&) = default;
|
||||
constexpr underflow_error& operator=(const underflow_error&) = default;
|
||||
constexpr underflow_error(underflow_error&&) = default;
|
||||
constexpr underflow_error& operator=(underflow_error&&) = default;
|
||||
constexpr virtual ~underflow_error() noexcept { }
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~underflow_error() noexcept { }
|
||||
#else
|
||||
explicit underflow_error(const string& __arg) _GLIBCXX_TXN_SAFE;
|
||||
#if __cplusplus >= 201103L
|
||||
|
||||
@@ -61,9 +61,12 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
_GLIBCXX26_CONSTEXPR bad_exception() _GLIBCXX_USE_NOEXCEPT { }
|
||||
|
||||
#if __cplusplus >= 202400L
|
||||
constexpr virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN noexcept {}
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN noexcept {}
|
||||
|
||||
constexpr virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN noexcept
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN
|
||||
noexcept
|
||||
{
|
||||
return "std::bad_exception";
|
||||
}
|
||||
|
||||
@@ -63,7 +63,8 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
public:
|
||||
_GLIBCXX26_CONSTEXPR exception() _GLIBCXX_NOTHROW { }
|
||||
#if __cplusplus >= 202400L
|
||||
constexpr virtual ~exception() _GLIBCXX_TXN_SAFE_DYN noexcept {}
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~exception() _GLIBCXX_TXN_SAFE_DYN noexcept {}
|
||||
#else
|
||||
virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
|
||||
#endif
|
||||
@@ -77,7 +78,8 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
/** Returns a C-style character string describing the general cause
|
||||
* of the current error. */
|
||||
#if __cplusplus >= 202400L
|
||||
constexpr virtual const char*
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual const char*
|
||||
what() const _GLIBCXX_TXN_SAFE_DYN noexcept { return "std::exception"; }
|
||||
#else
|
||||
virtual const char*
|
||||
|
||||
@@ -107,7 +107,8 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
void* _M_exception_object;
|
||||
|
||||
#if __cplusplus >= 202400L
|
||||
constexpr explicit exception_ptr(void* __e) noexcept
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline explicit exception_ptr(void* __e) noexcept
|
||||
: _M_exception_object(__e)
|
||||
{
|
||||
if (_M_exception_object)
|
||||
|
||||
@@ -72,7 +72,8 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
nested_exception& operator=(const nested_exception&) noexcept = default;
|
||||
|
||||
#if __cplusplus >= 202400L
|
||||
constexpr virtual ~nested_exception() noexcept {}
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~nested_exception() noexcept {}
|
||||
#else
|
||||
virtual ~nested_exception() noexcept;
|
||||
#endif
|
||||
|
||||
@@ -227,9 +227,11 @@ namespace std
|
||||
_GLIBCXX26_CONSTEXPR bad_cast() _GLIBCXX_USE_NOEXCEPT { }
|
||||
|
||||
#if __cplusplus >= 202400L
|
||||
constexpr virtual ~bad_cast() noexcept {}
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~bad_cast() noexcept {}
|
||||
|
||||
constexpr virtual const char* what() const noexcept
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual const char* what() const noexcept
|
||||
{
|
||||
return "std::bad_cast";
|
||||
}
|
||||
@@ -253,9 +255,11 @@ namespace std
|
||||
_GLIBCXX26_CONSTEXPR bad_typeid () _GLIBCXX_USE_NOEXCEPT { }
|
||||
|
||||
#if __cplusplus >= 202400L
|
||||
constexpr virtual ~bad_typeid() noexcept {}
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual ~bad_typeid() noexcept {}
|
||||
|
||||
constexpr virtual const char* what() const noexcept
|
||||
[[__gnu__::__gnu_inline__]]
|
||||
constexpr inline virtual const char* what() const noexcept
|
||||
{
|
||||
return "std::bad_typeid";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user