Why is gcc not catching an exception from a multi target function?

Viewed 113

I'm using the target attribute to generate different function implementations depending on the CPU architecture. If one of the functions throws an exception it doesn't get caught if I compile with gcc, but with clang it works as expected. If there is only a single implementation of the function it does work for gcc as well.

Is this a bug in gcc?

Example (godbolt):

#include <stdexcept>
#include <iostream>

using namespace std;

__attribute__((target("default")))
void f() {
    throw 1;

}

__attribute__((target("sse4.2,bmi")))
void f() {
    throw 2;
}

int main()
{
    try {
        f();
    }
    catch(... )
    {
        std::cout << "Caught exception" << std::endl;
    }
}

Output of gcc:

terminate called after throwing an instance of 'int'

Output of clang:

Caught exception
1 Answers

I reported this and a GCC developer confirmed it as a bug: link

For now a workaround seems to wrap the function and use the gnu::noipa attribute to disable interprocedural optimizations:

__attribute__((target("default")))
void f() {
    throw 1;
}

__attribute__((target("sse4.2")))
void f() {
    throw 2;
}
[[gnu::noipa]]
void f1()
{
    f();
}

int main()
{
    try {
        f1();
    }
    catch(... )
    {
        return 0;
    }
    return 1;
}

The bug is now fixed in gcc's master branch and should be released with gcc version 13.

Related