If I compile the following code:
void f() {
int* ptr = 0;
try {
*ptr = 9;
} catch (...) {
printf("caught");
}
Gcc doesn`t compile code that it considers unreachable, so the resulting assembly does not contain the catch block. How do I make GCC compile everything?
I need this because I am researching the possibility of passing C exceptions from the kernel to user programs, so if the code above is executed, the kernel will throw an exception after *ptr=9 that should be caught in the catch block.
CodePudding user response:
The only way I can think of accomplishing this without creating a new compiler backend would be to wrap the standard types with classes (e.g., int
becomes Int
). These class replacements for the standard types would use operator overloading that could be recognized as possibly throwing an exception.
This would be a hack, of course. But, I have seen this technique used by an automatic differentiation generator.
However, if the compiler can determine a priori that the code would generate undefined behavior, then there is not much you can do about what it decides to do with that knowledge. It can just decide the whole block of code would never execute, and skip generating any code at all.
CodePudding user response:
Your specific example is partly covered by -fno-delete-null-pointer-checks
. With this option, Clang treats null pointer dereferences as externally observable behavior, and does not elide them. However, it seems this option does not play well with -fnon-call-exceptions
(at least in Clang 11), which is expect to emit exception handling tables for code that can trap. GCC handles this as expected and generates code for the catch
handler.