fix: define (non-empty) PYBIND11_EXPORT_EXCEPTION only under macOS. (#4298)

Background: #2999, #4105, #4283, #4284

In a nutshell:

* Only macOS actually needs `PYBIND11_EXPORT_EXCEPTION` (#4284).

* Evidently (#4283), under macOS `PYBIND11_EXPORT_EXCEPTION` does not run the risk of introducing ODR violations,

* but evidently (#4283) under Linux it does, in the presumably rare/unusual situation that `RTLD_GLOBAL` is used.

* Windows does no have the equivalent of `RTLD_GLOBAL`, therefore `PYBIND11_EXPORT_EXCEPTION` has no practical benefit, on the contrary, noisy warning suppression pragmas are needed, therefore it is best left empty.
This commit is contained in:
Ralf W. Grosse-Kunstleve 2022-10-31 10:36:26 -07:00 committed by Ralf W. Grosse-Kunstleve
parent c3987b1aad
commit 59b45e0abf
3 changed files with 9 additions and 27 deletions

View File

@ -177,9 +177,12 @@ section.
may be explicitly (re-)thrown to delegate it to the other, may be explicitly (re-)thrown to delegate it to the other,
previously-declared existing exception translators. previously-declared existing exception translators.
Note that ``libc++`` and ``libstdc++`` `behave differently <https://stackoverflow.com/questions/19496643/using-clang-fvisibility-hidden-and-typeinfo-and-type-erasure/28827430>`_ Note that ``libc++`` and ``libstdc++`` `behave differently under macOS
with ``-fvisibility=hidden``. Therefore exceptions that are used across ABI boundaries need to be explicitly exported, as exercised in ``tests/test_exceptions.h``. <https://stackoverflow.com/questions/19496643/using-clang-fvisibility-hidden-and-typeinfo-and-type-erasure/28827430>`_
See also: "Problems with C++ exceptions" under `GCC Wiki <https://gcc.gnu.org/wiki/Visibility>`_. with ``-fvisibility=hidden``. Therefore exceptions that are used across ABI
boundaries need to be explicitly exported, as exercised in
``tests/test_exceptions.h``. See also:
"Problems with C++ exceptions" under `GCC Wiki <https://gcc.gnu.org/wiki/Visibility>`_.
Local vs Global Exception Translators Local vs Global Exception Translators

View File

@ -96,13 +96,10 @@
#endif #endif
#if !defined(PYBIND11_EXPORT_EXCEPTION) #if !defined(PYBIND11_EXPORT_EXCEPTION)
# ifdef __MINGW32__ # if defined(__apple_build_version__)
// workaround for:
// error: 'dllexport' implies default visibility, but xxx has already been declared with a
// different visibility
# define PYBIND11_EXPORT_EXCEPTION
# else
# define PYBIND11_EXPORT_EXCEPTION PYBIND11_EXPORT # define PYBIND11_EXPORT_EXCEPTION PYBIND11_EXPORT
# else
# define PYBIND11_EXPORT_EXCEPTION
# endif # endif
#endif #endif
@ -925,12 +922,6 @@ using expand_side_effects = bool[];
PYBIND11_NAMESPACE_END(detail) PYBIND11_NAMESPACE_END(detail)
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable : 4275)
// warning C4275: An exported class was derived from a class that wasn't exported.
// Can be ignored when derived from a STL class.
#endif
/// C++ bindings of builtin Python exceptions /// C++ bindings of builtin Python exceptions
class PYBIND11_EXPORT_EXCEPTION builtin_exception : public std::runtime_error { class PYBIND11_EXPORT_EXCEPTION builtin_exception : public std::runtime_error {
public: public:
@ -938,9 +929,6 @@ public:
/// Set the error using the Python C API /// Set the error using the Python C API
virtual void set_error() const = 0; virtual void set_error() const = 0;
}; };
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
#define PYBIND11_RUNTIME_EXCEPTION(name, type) \ #define PYBIND11_RUNTIME_EXCEPTION(name, type) \
class PYBIND11_EXPORT_EXCEPTION name : public builtin_exception { \ class PYBIND11_EXPORT_EXCEPTION name : public builtin_exception { \

View File

@ -623,12 +623,6 @@ inline std::string error_string() {
PYBIND11_NAMESPACE_END(detail) PYBIND11_NAMESPACE_END(detail)
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable : 4275 4251)
// warning C4275: An exported class was derived from a class that wasn't exported.
// Can be ignored when derived from a STL class.
#endif
/// Fetch and hold an error which was already set in Python. An instance of this is typically /// Fetch and hold an error which was already set in Python. An instance of this is typically
/// thrown to propagate python-side errors back through C++ which can either be caught manually or /// thrown to propagate python-side errors back through C++ which can either be caught manually or
/// else falls back to the function dispatcher (which then raises the captured error back to /// else falls back to the function dispatcher (which then raises the captured error back to
@ -688,9 +682,6 @@ private:
/// crashes (undefined behavior) if the Python interpreter is finalizing. /// crashes (undefined behavior) if the Python interpreter is finalizing.
static void m_fetched_error_deleter(detail::error_fetch_and_normalize *raw_ptr); static void m_fetched_error_deleter(detail::error_fetch_and_normalize *raw_ptr);
}; };
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
/// Replaces the current Python error indicator with the chosen error, performing a /// Replaces the current Python error indicator with the chosen error, performing a
/// 'raise from' to indicate that the chosen error was caused by the original error. /// 'raise from' to indicate that the chosen error was caused by the original error.