RFC: allowing EH constructs, but not generating handlers/cleanups

-fno-exceptions causes EH constructs such as try/catch, function-try-blocks, and throw expressions to be diagnosed with a severe error. That is, -f[no-]exceptions controls a language-support property.

For experiments in evaluating the cost of (unused) exception handling, and for cases where components are being deployed with the expectation that exceptions will not be thrown, etc. it is useful to allow EH constructs in the source, but to generate code with no handlers or cleanups.

I think that it still makes sense under such a mode to allow throw expressions to throw. This is consistent with -fno-exceptions still calling __cxa_bad_cast and __cxa_bad_typeid (which GCC also does, but not with __cxa_throw_bad_array_new_length).

That is, the proposed semantics is essentially the same as for -fno-exceptions, except to treat try/catch and function-try-blocks as just normal code introducing no handlers, and to allow throw expressions.

-fno-exceptions already suppresses creation of cleanups for unwinding and the ignoring of exception specifications.

I like to think of this as -fignore-exceptions. I have a use for this, and I would like to know what people think.

– HT

To summarize, code compiled with -fignore-exceptions can throw, but can’t catch anything. All exceptions just unwind through all such code. Is that right? -Hal

-fno-exceptions causes EH constructs such as try/catch,
function-try-blocks, and throw expressions to be diagnosed with a severe
error. That is, -f[no-]exceptions controls a language-support property.

For experiments in evaluating the cost of (unused) exception handling, and
for cases where components are being deployed with the expectation that
exceptions will not be thrown, etc. it is useful to allow EH constructs in
the source, but to generate code with no handlers or cleanups.

I think that it still makes sense under such a mode to allow throw
expressions to throw. This is consistent with -fno-exceptions still calling
__cxa_bad_cast and __cxa_bad_typeid (which GCC also does, but not with
__cxa_throw_bad_array_new_length).

That is, the proposed semantics is essentially the same as for
-fno-exceptions, except to treat try/catch and function-try-blocks as just
normal code introducing no handlers, and to allow throw expressions.

-fno-exceptions already suppresses creation of cleanups for unwinding and
the ignoring of exception specifications.

I like to think of this as -fignore-exceptions. I have a use for this, and
I would like to know what people think.

To summarize, code compiled with -fignore-exceptions can throw, but can't
catch anything. All exceptions just unwind through all such code. Is that
right?

That depends on what you mean by "unwind". Exceptions will go past all such
code without executing destructors.

-fno-exceptions causes EH constructs such as try/catch,
function-try-blocks, and throw expressions to be diagnosed with a severe
error. That is, -f[no-]exceptions controls a language-support property.

For experiments in evaluating the cost of (unused) exception handling, and
for cases where components are being deployed with the expectation that
exceptions will not be thrown, etc. it is useful to allow EH constructs in
the source, but to generate code with no handlers or cleanups.

I think that it still makes sense under such a mode to allow throw
expressions to throw. This is consistent with -fno-exceptions still calling
__cxa_bad_cast and __cxa_bad_typeid (which GCC also does, but not with
__cxa_throw_bad_array_new_length).

That is, the proposed semantics is essentially the same as for
-fno-exceptions, except to treat try/catch and function-try-blocks as just
normal code introducing no handlers, and to allow throw expressions.

-fno-exceptions already suppresses creation of cleanups for unwinding and
the ignoring of exception specifications.

I like to think of this as -fignore-exceptions. I have a use for this, and
I would like to know what people think.

To summarize, code compiled with -fignore-exceptions can throw, but can't
catch anything. All exceptions just unwind through all such code. Is that
right?

That depends on what you mean by "unwind". Exceptions will go past all such
code without executing destructors.

Will throwing always result in calling std::terminate()? If so, does
that call happen immediately upon executing the throw statement?

Or, if you have one TU compiled with -fignore-exceptions that throws,
and a second TU with -fno-ignore-exceptions that catches the exception
thrown from the first TU, can the exception still be caught?

~Aaron

>>
>>
>>
>> -fno-exceptions causes EH constructs such as try/catch,
>> function-try-blocks, and throw expressions to be diagnosed with a severe
>> error. That is, -f[no-]exceptions controls a language-support property.
>>
>> For experiments in evaluating the cost of (unused) exception handling,
and
>> for cases where components are being deployed with the expectation that
>> exceptions will not be thrown, etc. it is useful to allow EH constructs
in
>> the source, but to generate code with no handlers or cleanups.
>>
>> I think that it still makes sense under such a mode to allow throw
>> expressions to throw. This is consistent with -fno-exceptions still
calling
>> __cxa_bad_cast and __cxa_bad_typeid (which GCC also does, but not with
>> __cxa_throw_bad_array_new_length).
>>
>> That is, the proposed semantics is essentially the same as for
>> -fno-exceptions, except to treat try/catch and function-try-blocks as
just
>> normal code introducing no handlers, and to allow throw expressions.
>>
>> -fno-exceptions already suppresses creation of cleanups for unwinding
and
>> the ignoring of exception specifications.
>>
>> I like to think of this as -fignore-exceptions. I have a use for this,
and
>> I would like to know what people think.
>>
>>
>> To summarize, code compiled with -fignore-exceptions can throw, but
can't
>> catch anything. All exceptions just unwind through all such code. Is
that
>> right?
>
> That depends on what you mean by "unwind". Exceptions will go past all
such
> code without executing destructors.

Will throwing always result in calling std::terminate()? If so, does
that call happen immediately upon executing the throw statement?

Or, if you have one TU compiled with -fignore-exceptions that throws,
and a second TU with -fno-ignore-exceptions that catches the exception
thrown from the first TU, can the exception still be caught?

The exception can still be caught.

>>
>>
>>
>> -fno-exceptions causes EH constructs such as try/catch,
>> function-try-blocks, and throw expressions to be diagnosed with a
>> severe
>> error. That is, -f[no-]exceptions controls a language-support property.
>>
>> For experiments in evaluating the cost of (unused) exception handling,
>> and
>> for cases where components are being deployed with the expectation that
>> exceptions will not be thrown, etc. it is useful to allow EH constructs
>> in
>> the source, but to generate code with no handlers or cleanups.
>>
>> I think that it still makes sense under such a mode to allow throw
>> expressions to throw. This is consistent with -fno-exceptions still
>> calling
>> __cxa_bad_cast and __cxa_bad_typeid (which GCC also does, but not with
>> __cxa_throw_bad_array_new_length).
>>
>> That is, the proposed semantics is essentially the same as for
>> -fno-exceptions, except to treat try/catch and function-try-blocks as
>> just
>> normal code introducing no handlers, and to allow throw expressions.
>>
>> -fno-exceptions already suppresses creation of cleanups for unwinding
>> and
>> the ignoring of exception specifications.
>>
>> I like to think of this as -fignore-exceptions. I have a use for this,
>> and
>> I would like to know what people think.
>>
>>
>> To summarize, code compiled with -fignore-exceptions can throw, but
>> can't
>> catch anything. All exceptions just unwind through all such code. Is
>> that
>> right?
>
> That depends on what you mean by "unwind". Exceptions will go past all
> such
> code without executing destructors.

Will throwing always result in calling std::terminate()? If so, does
that call happen immediately upon executing the throw statement?

Or, if you have one TU compiled with -fignore-exceptions that throws,
and a second TU with -fno-ignore-exceptions that catches the exception
thrown from the first TU, can the exception still be caught?

The exception can still be caught.

Thank you -- I think this is useful functionality. I'm a little bit
worried about the proliferation of exception-disabling-related flags,
but that's more an issue with how this gets surfaced rather than the
functionality itself.

~Aaron