Skip to content
Commit 9b7b48f4 authored by Amy spark's avatar Amy spark 👉
Browse files

global: Fix ECM exception handling semantics mismatch in MSVC

According to the Extra CMake Modules documentation [1],

> kde_enable_exceptions()
>
> Enables exceptions for C++ source files compiled for the CMakeLists.txt
> file in the current directory and all subdirectories.

What isn't listed there, however, is that exceptions are enabled through
the usage of -fexceptions (GCC/Clang) and -EHsc (MSVC/Intel) [2]. All
good... except that those mean slightly different things:

> -fexceptions
>
>    Enable exception handling. Generates extra code needed to propagate
>    exceptions. For some targets, this implies GCC generates frame
>    unwind information for all functions, which can produce significant
>    data size overhead, although it does not affect execution. If you do
>    not specify this option, GCC enables it by default for languages
>    like C++ that normally require exception handling, and disables it
>    for languages like C that do not normally require it. However, you
>    may need to enable this option when compiling C code that needs to
>    interoperate properly with exception handlers written in C++. You
>    may also wish to disable this option if you are compiling older C++
>    programs that don’t use exception handling.

(source: [3])

> c
> When used with /EHs, the compiler assumes that functions declared as
> extern "C" never throw a C++ exception. It has no effect when used with
> /EHa (that is, /EHca is equivalent to /EHa). /EHc is ignored if /EHs or
> /EHa aren't specified.

(source: [4])

These two put together mean that any exception thrown in a callstack
with C code in between works in Unix-y compilers, while they would
crash straight to Qt/QtConcurrent's event loop in MSVC.

The only affected piece of code is the JPEG error catcher,
introduced by Halla in 5c4c327a, so
I added a file-level workaround there. A Krita-wide workaround is not
possible at the moment; all consumers of kritapigment would need the
same surgical workaround, because OpenEXR also injects /EHsc through
its exported targets. This was already reported upstream [5].

[1]: https://api.kde.org/ecm/kde-module/KDECompilerSettings.html
[2]: https://invent.kde.org/frameworks/extra-cmake-modules/-/blob/v5.101.0/kde-modules/KDECompilerSettings.cmake#L502-526
[3]: https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/Code-Gen-Options.html#index-fexceptions
[4]: https://learn.microsoft.com/en-us/cpp/build/reference/eh-exception-handling-model?view=msvc-170#arguments
[5]: https://github.com/AcademySoftwareFoundation/openexr/issues/1326

CCBUG: 361746
CCMAIL: kimageshop@kde.org
parent ab3dfaa8
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment