[llvm-commits] add nounwind flag to BasicBlock
baldrick at free.fr
Thu Mar 13 03:15:27 PDT 2008
> Ah! I didn't realize that nounwind on a CallInst actually meant that it
> must call terminate in c++, I thought it was just "undefined behaviour
> happens here".
right: when unwinding an exception, if the unwinder sees it is about to
unwind through a call marked 'nounwind' then it calls terminate. This
ensures that the 'nounwind' marking was correct: no exception will unwind
past this point. However note that this is a C++ issue: C++ allows calls
to be marked 'nounwind' even if the called function can throw an exception,
and thus also adds a mechanism to ensure that the nounwind indication was
not a lie: the C++ personality function redirects execution to "terminate".
In Ada by contrast there is no way of having a call to a function be marked
'nounwind' if that function might throw an exception, so the Ada personality
function doesn't give a damn whether such calls get marked nounwind in the
dwarf exception tables or not.
> I think it's the same as the nounwind flag on Functions though, no?
No. A call can be marked 'nounwind' even if the callee can throw
exceptions. For example, you may know that the callee will not
unwind given the parameters you pass to it, so it is reasonable to
mark the call 'nounwind' even though it would be wrong to mark the
callee 'nounwind'. Also, in the case of C++, calls may be marked
'nounwind' even if the callee may throw given the parameters passed
to it: in this case the unwinder takes care not to unwind through
the call (see above), which ensures that the 'nounwind' marking on
the call was correct. In this case too the callee cannot correctly
be marked 'nounwind'.
> They don't have the same problem that the CallInst does?
I don't think function 'nounwind' markings are needed for correct
C++ semantics, only call 'nounwind' markings. That said, if all
the calls that a function performs are marked 'nounwind' then it is
correct and useful to mark the function 'nounwind' (the LLVM prune-eh
pass does this). I think the only other way a function can be marked
'nounwind' is if the user used the nothrow attribute (this includes
standard library functions which have marked themselves nothrow because
they know they cannot throw, eg: math functions). If the user made a
mistake then they get what they deserve if the function throws, and I
don't think there is any requirement to call terminate in this case,
though if you do call it then that is ok. For example, in the case
of an indirect call it is impossible in general to know that you need
to put a 'nounwind' marking in the dwarf eh table (the marking goes
on calls, not on functions) because you can't know whether the callee
has such a marking or not. This example shows that there cannot be a
requirement that calls to 'nounwind' functions that do in fact unwind
should result in a call to terminate.
Summary: if a function marked 'nounwind' unwinds [through a call that
isn't marked 'nounwind'] then the result is undefined; if a call marked
'nounwind' unwinds then the result is defined by the exception handling
personality function, and for this to work such calls need to be marked
in the dwarf eh tables at codegen time. In the case of Ada the result
is in fact that the unwinder happily keeps on unwinding, while in the
case of C++ execution branches to "terminate".
More information about the llvm-commits