[LLVMdev] LLVM Exception Handling

Renato Golin rengolin at systemcall.org
Sun Sep 26 11:49:27 PDT 2010


On 26 September 2010 13:08, Eugene Toder <eltoder at gmail.com> wrote:
>  %s = invoke i32 @v(i32 %o) to label %ok
>                   unwind %x to label %catch
> ok:
>  ret i32 %s
>
> catch:
>  %type = call i32 @exception_type(i8* %x)
>  %r = icmp eq i32 %type, 255 ; 255 is DivisionByZeroException type
>  br i1 %r, label %bad, label %worse
>
> bad:
>  ret i32 -1
>
> worse:
>  ret i32 -2
> }

That could be enough for SJ/LJ (I have no idea), but it certainly is
not for Dwarf exceptions. When an invoke throws an exception, the flow
doesn't go directly to the catch area. First you go to a cleanup area,
where you have to deallocate all temporaries, in which you can also
throw again, or even terminate.

Then you go the analysis of the exception structure, to see if that's
valid in accordance with the function specification and the
personality routine (when the EH table goes in context). It is only
after that that you go through the catch blocks by: first checking the
type is the same as the catch block is catching for and entering the
block if it is, or jumping to the next type check/catch block.

At the end, if it was not caught, you have to jump to another cleanup
area before throwing again, and continue with the unwinding cycle on
the caller function. ALL that is generated by the compiler and happen
oblivious to the user's code. The flow only return to the user's code
if you enter in a catch area.

Which means that, %type is NOT a number, it is a TypeInfo, and it's
not inside the catch area, but rather before it. I assume, in your
example, that the *icmp* is user code. If %x is what came from the
catch (Type& x) {}, you'll have to do one of two things to get %type:

1. Give the user an intrinsic, which breaks the EH contract
2. Give the type directly, which also breaks the contract (they also
need the value)

If the *icmp* is not user code, this is even worse, because an
exception handling code automatically generated by the compiler will
be returning a value from a function, completely breaking the EH
contract.

In other words, this approach will not work with Dwarf exceptions.



> I going with invoke instruction that returns exception pointer (which
> feels right to me) maybe this is a good candidate for using union type

I'm an advocate of re-introducing unions, but in this case I think
it'll rather obfuscate things even more...

Don't take me wrong, I'm not against the change, really. If the docs
say there's something wrong, I thing we should fix it, but I fear that
the issue is being seen from the sj/lj point of view only (or
mainly)...

Is there any language front-end (other than C++) using exceptions? We
might consider their views as well...

cheers,
--renato




More information about the llvm-dev mailing list