[llvm-dev] help me understand how nounwind attribute on functions works?

Sean Silva via llvm-dev llvm-dev at lists.llvm.org
Thu Feb 9 13:00:45 PST 2017


On Feb 8, 2017 5:46 PM, "Mehdi Amini via llvm-dev" <llvm-dev at lists.llvm.org>
wrote:


On Feb 8, 2017, at 12:58 PM, Reid Kleckner via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

I think this behavior is intended to allow better LTO between C and C++.
Consider this kind of code:

// foo.h
extern "C" int doThing(bool canThrow);
// foo.cpp
int doThing(bool canThrow) {
  ...
  if (hadError) {
    if (canThrow) throw MyException; else return -1;
  }
}
// bar.c
#include "foo.h"
void f() {
  doThing(false); // don't declare doThing as nounwind
}
// baz.cpp
...
  doThing(true);

Basically, compiling a C declaration for a function is not an assertion
that it never throws an exception. However, *defining* a function in a C TU
implies that it will not throw an exception.


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?


Given the semantics, aren't we allowed to infer it transitively? I.e. if a
callee of a nounwind function does dynamically unwind through the nounwind
caller, then it is UB.

-- Sean Silva


—
Mehdi





On Sun, Feb 5, 2017 at 8:32 AM, Andrew Kelley via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> from http://llvm.org/docs/LangRef.html:
>
> nounwind
>> This function attribute indicates that the function never raises an
>> exception. If the function does raise an exception, its runtime behavior is
>> undefined. However, functions marked nounwind may still trap or generate
>> asynchronous exceptions. Exception handling schemes that are recognized by
>> LLVM to handle asynchronous exceptions, such as SEH, will still provide
>> their implementation defined semantics.
>
>
> Some things I noticed by looking at various C test programs with clang -S
> -emit-llvm:
>
>  * If a function definition is provided, it gets nounwind, even if it
> calls a non-nounwind function
>  * If a function is external (no definition provided), it does not get
> nounwind
>
> What I don't understand is:
>  * A non-nounwind function that calls a nounwind function, wouldn't the
> ability for an exception to be thrown transfer? I thought if you don't
> catch an exception, it bubbles up to the caller and so on.
>  * More importantly, if compiling in C mode, why doesn't every function
> have nounwind? I thought that C does not have exceptions, so calling a
> function and having it throw an exception would be undefined behavior
> anyway. Wouldn't that mean every function should be nounwind?
>
> Regards,
> Andrew
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
>
_______________________________________________
LLVM Developers mailing list
llvm-dev at lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



_______________________________________________
LLVM Developers mailing list
llvm-dev at lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170209/a6cd78d1/attachment.html>


More information about the llvm-dev mailing list