This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: avoid unnecessary register saves for setjmp


Andrew Haley <aph@redhat.com> writes:

> Well, okay: the front end has turned sjlj into exceptions, and the
> back end has turned it all back again.  We get the advantage of better
> analysis in the middle.  No problem there; I am only referring to
> user-visible changes.

I should say that the primary reason I think this would be a good
change for GCC's users (not just for internal-to-GCC reasons) is that
it makes the user-visible semantics of setjmp/longjmp much nicer.
Consider

void foo(jmp_buf env) { longjmp(env, 1); }

void bar(void)
{
  int x = 12;
  jmp_buf env;

  if (setjmp (env) == 0)
    {
      x = 23;
      foo();
    }
  else
    printf("%d\n", x);  // oops! value of x is undefined
}

versus

void foo(jmp_buf env) { throw 1; }

void bar(void)
{
  int x = 12;
  jmp_buf env;

  try
    {
      x = 23;
      foo();
    }
  catch (int)
    printf("%d\n", x);  // defined to print 23
}

>From a language-design perspective it's desirable for x to have the
value 23 in both fragments.  (Leaving out the volatile on x is
intentional.)  Its being undefined in C is a source of hard-to-find
bugs.  It happens because longjmp() can't know which registers need
restoring, whereas the EH unwinder does know and can get it
(abstractly) right.  So by using the EH unwinder for longjmp we clean
up a nasty dark corner of the language.

To be fair, an argument against this change is that it would break
code that uses setjmp and longjmp to implement coroutine linkage.
(The set/get/make/swapcontext calls are better for this, but that
doesn't mean everyone uses them.)

zw


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]