<div dir="ltr">It is my belief that all functions compiled with -fno-exceptions (which is the default for C code, but notably not the ONLY option) <i>ought to</i> (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.<div><br></div><div>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.</div><div><br></div><div>Unfortunately, clang implements noexcept very inefficiently, and so doing that in clang right now would have a huge amount of overhead.</div><div><br></div><div>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.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Feb 9, 2017 at 12:12 PM, David Chisnall via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On 9 Feb 2017, at 08:41, Reid Kleckner via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br>
><br>
> On Wed, Feb 8, 2017 at 5:45 PM, Mehdi Amini <<a href="mailto:mehdi.amini@apple.com">mehdi.amini@apple.com</a>> wrote:<br>
> What isn’t clear to me still is : why shouldn't this be transitive?<br>
> 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?<br>
><br>
> 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.<br>
<br>
</div></div>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.<br>
<br>
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.<br>
<br>
David<br>
<div class="HOEnZb"><div class="h5"><br>
______________________________<wbr>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
</div></div></blockquote></div><br></div>