[llvm-dev] help me understand how nounwind attribute on functions works?
James Y Knight via llvm-dev
llvm-dev at lists.llvm.org
Thu Feb 9 09:40:46 PST 2017
It is my belief that all functions compiled with -fno-exceptions (which is
the default for C code, but notably not the ONLY option) *ought to* (for
QoI reasons, not a standards requirement) get the equivalent of noexcept
behavior. That is: guaranteed to abort if an exception is thrown through it.
This doesn't happen now on x86-64, due to the default async unwind tables
as you mention. That used to be the case on x86-32...although it seems that
async unwind tables are now on by default there too, in some cases.
Unfortunately, clang implements noexcept very inefficiently, and so doing
that in clang right now would have a huge amount of overhead.
Clang implements C++ noexcept by inserting explicit catch code, which then
calls terminate. GCC, on the other hand, just sets up the exception table
appropriately to make the unwinder itself do that. It would be really good
to fix that, but it's my understanding that it'd be somewhat difficult in
llvm's current exceptions model.
On Thu, Feb 9, 2017 at 12:12 PM, David Chisnall via llvm-dev <
llvm-dev at lists.llvm.org> wrote:
> On 9 Feb 2017, at 08:41, Reid Kleckner via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
> > On Wed, Feb 8, 2017 at 5:45 PM, Mehdi Amini <mehdi.amini at apple.com>
> > What isn’t clear to me still is : why shouldn't this be transitive?
> > In the example you’re showing, for a caller of f() in bar, what is the
> advantage of knowing that f() is nounwind if it an exception can still be
> thrown? What does it allow?
> > We know an exception cannot unwind out of f. An exception can be thrown
> inside something that f calls, but it must be caught before it unwinds
> beyond f.
> Why? With the x86-64 ABI, for example, f is required to emit async unwind
> tables. It has a personality function that knows how to handle cleanups,
> but there are none here, so the generic unwinder will happily unwind
> through the code. The only ways to prevent exceptions from being
> propagated are to explicitly catch them, or to use something like a C++
> exception specifier so that the personality function will explicitly block
> exception propagation.
> In this example, given that doThing is not marked as noexcept, we will
> emit unwind tables that explicitly allow unwinding through f; however, when
> the unwinder tries to unwind into the next stack frame it will find that
> there is no unwind record. Depending on how lazy we are in defining the PC
> ranges in the unwind table, this will either cause stack corruption or a
> run-time abort from well-formed code.
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the llvm-dev