Notes about __cxa_end_catch
Christophe de Dinechin
ddd at cup.hp.com
Fri Dec 17 02:29:40 UTC 1999
Coleen Phillimore wrote:
>
> /*
> Regarding the discussion of __cxa_end_catch:
>
> If you need to clean up more than one live exception from a
> catch handler, don't you need a 'count' parameter to
> __cxa_end_catch? In this case, you destroy both X and
> Y objects (whether or not they're both on the stack,
> or just X is).
>
> Our equivalent of end_catch has a count parameter which
> is set to the number of live exception objects to
> delete and is used for branching out of the nested catch
> clause (not by rethrow).
> */
> struct X { X(); ~X(); };
> struct Y { Y(); ~Y(); };
> extern "C" int printf(const char *,...);
> main()
> {
> try {
> throw X();
> } catch (X x) {
> try {
> throw Y();
> } catch(...) {
> //generates __cxa_end_catch(/*levels=*/2)
> return 1;
> }
> }
> }
>
Two __cxa_end_catch calls need to be generated here, since you are closing two
catch clauses. Thus, the code for the above will look like:
main:
X *thrown = __allocate_exception(sizeof(X));
__throw(thrown); // Landing pad LP1
LP1:
// Pushes the X on the caught stack
X* xptr = __begin_catch(exc)
Y *thrown = __allocate_exception(sizeof(Y));
__throw(thrown); // Landing pad LP2
LP2:
// Pushes the Y on the exception stack
return_value = 1;
goto exiting_inner_catch;
exiting_inner_catch:
// Pops Y off the stack, delete it
__end_catch();
goto exiting_outer_catch;
exiting_outer_catch:
// Pops X off the stack, delete it
__end_catch();
goto return_point;
return_point:
...
This is very similar to what you need to do for locals in each of the catch
blocks anyway. I am against having an extra argument, because it would be quite
detrimental in the general case (where you close only one catch clause).
Christophe
More information about the cxx-abi-dev
mailing list