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.

Reply via email to