Description
Reproducer:
class Error {
public:
Error(const char *) noexcept;
};
void test()
{
struct Guard {
~Guard() {}
} __guard;
throw Error("testing");
}
it will trigger
In the traditional pipeline, we would generate an invoke and one to unreachable BB and one to the invoke dest BB.
I tried to take a look. But the logics about creating and handling for invoke dest BB looks pretty much more different than the traditional pipeline.
e.g., in clangir, the methods to getInvokeDestImpl
and emitLandingPad
will take a tryOp argument
clangir/clang/lib/CIR/CodeGen/CIRGenFunction.h
Lines 1838 to 1853 in 888f00c
while it is not the case in traditional pipeline
clangir/clang/lib/CodeGen/CodeGenFunction.h
Lines 762 to 764 in 888f00c
And also the return type in traditional pipeline is Block but the return type in CIR is Operation.
Other example including CIRGenFunction::getEHDispatchBlock
, where the implementation in traditional pipeline looks much simpler:
clangir/clang/lib/CodeGen/CGException.cpp
Lines 701 to 712 in 888f00c
than in CIR:
clangir/clang/lib/CIR/CodeGen/CIRGenException.cpp
Lines 784 to 820 in 888f00c
So I am pretty confused and have some questions.
- What is the design for supporting exceptions in CIR and what is the core design ideas?
Since I noticed the difference in supporting exceptions in CIR are traditional pipeline are much more different than other places I know. I guess there are some internal reasons and I want to know our plan for it.
- Can we move these handling for exceptions to later passes?
Given the existing implementation already differs from the traditional pipeline, I feel may be it will be good to move these handlings to later passes. It is helpful to make the CIRGen smaller and helpful for the analysis purpose. e.g., the generated CIR code may look like the codes in the frontend more.