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.