dim created this revision.
In https://reviews.llvm.org/rL279744, `__throw_XXX()` functions were
introduced, partially for compatibility with software compiled against
libstdc++. `_LIBCPP_NORETURN` is used on all of them, and when C++11
attributes are available, this gets defined as `[[noreturn]]`, instead of the
GNU-style `__attribute__((noreturn))` style.
However, this can cause trouble with some software, for example Mozilla
Firefox, which attempts to redefine several of these `__throw_XXX()` functions,
and but uses the `__attribute__((noreturn))` style exclusively. This then
leads to errors like:
/usr/include/c++/v1/new:130:1: error: function declared '[[noreturn]]' after
its first declaration
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++
spec
^
/usr/include/c++/v1/__config:283:30: note: expanded from macro
'_LIBCPP_NORETURN'
# define _LIBCPP_NORETURN [[noreturn]]
^
../../dist/include/mozilla/throw_gcc.h:35:1: note: declaration missing
'[[noreturn]]' attribute is here
__throw_bad_alloc(void)
^
See also https://bugs.freebsd.org/216186 and
https://bugzilla.mozilla.org/1329520 . In Firefox's case, the following list
of functions is affected:
__throw_bad_alloc(void)
__throw_bad_cast(void)
__throw_bad_exception(void)
__throw_bad_function_call(void)
__throw_bad_typeid(void)
__throw_domain_error(const char*)
__throw_invalid_argument(const char*)
__throw_ios_failure(const char*)
__throw_length_error(const char*)
__throw_logic_error(const char*)
__throw_out_of_range(const char*)
__throw_overflow_error(const char*)
__throw_range_error(const char*)
__throw_runtime_error(const char*)
__throw_system_error(int)
__throw_underflow_error(const char*)
To make it easier on third-party software, let's define a `LIBCPP_NORETURN_GNU`
variant, which always uses the `__attribute__((noreturn))` style, and apply it
specifically to the above list of functions.
This should also be merged to the 4.0 branch, when it has been committed.
https://reviews.llvm.org/D28981
Files:
include/__config
include/__locale
include/functional
include/new
include/stdexcept
include/system_error
include/typeinfo
Index: include/typeinfo
===
--- include/typeinfo
+++ include/typeinfo
@@ -190,7 +190,7 @@
} // std
_LIBCPP_BEGIN_NAMESPACE_STD
-_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
+_LIBCPP_NORETURN_GNU inline _LIBCPP_ALWAYS_INLINE
void __throw_bad_cast()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
Index: include/system_error
===
--- include/system_error
+++ include/system_error
@@ -664,7 +664,7 @@
static string __init(const error_code&, string);
};
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS
+_LIBCPP_NORETURN_GNU _LIBCPP_FUNC_VIS
void __throw_system_error(int ev, const char* what_arg);
_LIBCPP_END_NAMESPACE_STD
Index: include/stdexcept
===
--- include/stdexcept
+++ include/stdexcept
@@ -183,9 +183,9 @@
_LIBCPP_BEGIN_NAMESPACE_STD
// in the dylib
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
+_LIBCPP_NORETURN_GNU _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
-_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
+_LIBCPP_NORETURN_GNU inline _LIBCPP_ALWAYS_INLINE
void __throw_logic_error(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -196,7 +196,7 @@
#endif
}
-_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
+_LIBCPP_NORETURN_GNU inline _LIBCPP_ALWAYS_INLINE
void __throw_domain_error(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -207,7 +207,7 @@
#endif
}
-_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
+_LIBCPP_NORETURN_GNU inline _LIBCPP_ALWAYS_INLINE
void __throw_invalid_argument(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -218,7 +218,7 @@
#endif
}
-_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
+_LIBCPP_NORETURN_GNU inline _LIBCPP_ALWAYS_INLINE
void __throw_length_error(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -229,7 +229,7 @@
#endif
}
-_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
+_LIBCPP_NORETURN_GNU inline _LIBCPP_ALWAYS_INLINE
void __throw_out_of_range(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -240,7 +240,7 @@
#endif
}
-_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
+_LIBCPP_NORETURN_GNU inline _LIBCPP_ALWAYS_INLINE
void __throw_range_error(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -251,7 +251,7 @@
#endif
}
-_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
+_LIBCPP_NORETURN_GNU inline _LIBCPP_ALWAYS_INLINE
void __throw_overflow_error(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -262,7 +262,7 @@
#endif
}
-_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
+_LIBCPP_NORETURN_GNU inline _LIBCPP_ALWAYS_INLINE
void __throw_underflow_error(const char*__msg)
{
#ifndef