http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59920
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jason at gcc dot gnu.org,
| |jsm28 at gcc dot gnu.org
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Is it valid to longjmp to a setjmp where the containing function hasn't
terminated yet, but the scope in which the setjmp has been declared has been
left already?
I mean:
{ if (setjmp (jmp_buf) == 0) bar (); }
baz ();
and only baz () doing the longjmp? I see the standard talks about leaving the
caller, or about VLAs, and for C++ about destructors (but e.g. doesn't talk
about crossing constructors).
What about:
{ volatile int a; if (setjmp (jmp_buf) == 0) bar (&a, 0); else bar (&a, 1); }
{ volatile int b; baz (&b); }
and baz doing longjmp? This is effectively entering a scope that has been left
already, we could very well share the stack slot between a and b etc.
And for C++, say
struct A { A (); ~A (); };
...
{ volatile A a; if (setjmp (jmp_buf) == 0) bar (&a, 0); else bar (&a, 1); }
baz (&b);
? Supposedly there are no destructors that would make this invalid, on the
other side I think the C++ wording is as if setjmp was catch and longjmp throw,
and you really can't do that with throw/catch.
Anyway, the idea was that if longjmp to setjmp that has already left it's scope
was invalid, we could do some hacks and add the EDGE_ABNORMAL edges only from
calls within the scope of the setjmp. As the testcase has all the setjmp
surrounded by small scopes that have only one _setjmp together with at most a
couple of calls, this would dramatically reduce the number of EH edges,
SSA_NAMEs etc.