why does clang(llvm) do not optimize static throw/catch constructs?

tested with http://gcc.godbolt.org/ x86 clang 3.7 (experimental)

this silly throw/catch construct isn't optmized down to return 1

isn't there any exception-flow analysis in clang/llvm (even detecting this stupid case)
or is there a C++ standard limitation that forbits such optimizations - or does it overall
not make sense trying to optimize try/catch-flow in any way

int main()
{
   try
   {
     throw 1;
   }
   catch(int e)
   {
     return e;
   }
   return 0;
}

Doing this optimisation in the IR requires knowing what the personality function will do. This is nontrivial in the general case for C++, but would be relatively easy for simple cases like this.

The real question is whether it's worth it. How much C++ code in the real world actually does this? I'd imagine that only machine-generated code would, as C++ programmers know that this is a really slow way of writing goto. It's more likely to occur after inlining, but some analysis of how common it is would be useful for deciding whether it's worth doing.

David

We could actually optimize this example in LLVM if we wanted to, but this
we cannot:

void g();
void f() {
  try {
    throw 42;
  } catch (int e) {
    g();
  }
}

g's definition can rethrow, without ever having seen 'e':
void g() { throw; }

C++ requires EH schemes to maintain thread-local state, and it's pretty
opaque to LLVM. Optimizing it would require whole-program knowledge.

Even noexcept annotations won't help:
void g() noexcept {
  try {
    throw;
  } catch (int e) {
    // Now I have a copy of the exception object.
  }
}

so there is currently no exception optimization - my example was a test for optmization

its clear that externals or re-throwers are evil or impossible to analyse or its even not allowed to optimize

i was thinking (for example) about all these convert/etc. routines that using exceptions for recoverable errors - instead of error-codes
with always very local try/catch scopes for getting back the "error"-code

int parse_int(string)
{
   ...
   if(!number) throw not_a_number // or throw int as error-code
   ...
}

try
{
}
catch(not_a_number, ..., or int)
{
}

and how many calls some of these routines get in daily normal c++ code