This is the mail archive of the gcc@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: non-volatile automatic variables in setjmp tests


On Fri, Apr 5, 2019 at 6:25 PM Michael Matz <matz@suse.de> wrote:
>
> Hello,
>
> On Fri, 5 Apr 2019, Jozef Lawrynowicz wrote:
>
> > Some setjmp/longjmp tests[1] depend on the value of an auto set before setjmp
> > to to be retained after returning from the longjmp. As I understand, this
> > behaviour is actually undefined, according to the gccint manual.
> >
> > Section 3 "Interfacing to GCC Output" of gccint says:
> >   If you use longjmp, beware of automatic variables. ISO C says that automatic
> >   variables that are not declared volatile have undefined values after a
> >   longjmp. And this is all GCC promises to do, because it is very difficult to
> >   restore register variables correctly, and one of GCC’s features is that it
> >   can put variables in registers without your asking it to.
>
> That is very old text, from 1997, and doesn't reflect what GCC actually
> does, which is ...
>
> > However, ISO C says [2]:
> >   ... values of objects of automatic storage duration are unspecified if they
> >   meet all the following conditions:
> >   * They are local to the function containing the corresponding setjmp()
> >     invocation.
> >   * They do not have volatile-qualified type.
> >   * They are changed between the setjmp() invocation and longjmp() call.
>
> ... supporting this (and in any case if there's a direct conflict between
> the GCC docu and a relevant standard, then the former is likely the wrong
> one).  The are two modi: (a) the target has a setjmp/longjmp combination
> which restores all callee-saved registers (to the values at just before
> the setjmp call) and (b) the target doesn't save all these.
>
> For (a) GCC treats the setjmp call as a normal function call from a
> register-clobber perspective, so any auto variable live over the
> setjmp that is stored in a callee-saved register is restored to the
> pre-setjmp value.
>
> For (b) GCC makes sure to not allocate variables live over setjmp to
> registers.  This is the conservative assumption.
>
> Most targets in GCC follow the (b) model, even though the specific
> setjmp/longjmp mechanism would allow for (a).
>
> > gcc.dg/torture/stackalign/setjmp-1.c and
> > gcc.c-torture/execute/built-in-setjmp.c actually fail at execution for
> > msp430-elf @ -O1, because the auto being tested after the longjmp has not been
> > restored correctly.
>
> So the testcases should indeed work without volatile and you need to
> investigate why the restoring doesn't happen correctly.

There's one known "hole" in that the abnormal edges created to support all
of the above on GIMPLE are thrown away at RTL expansion time and
expected to be re-created "properly" but that doesn't actually happen.

The proper fix is to not throw them away but carry them over (with the
additional complication that you have to deal with that
find-many-sub-basic-block
case in some way).

Not sure if in this case we run into an RTL optimization that breaks things
(PRE / scheduling / invariant motion are candidates).

> > These tests feature a contrived way of making the auto appear used up to the
> > longjmp, so I wonder if they have been written deliberately without a
> > volatile, or if it was just an oversight.
> >
> > For msp430-elf @ -O1, this code to make the auto appear used is
> > ineffective as an optimization replaces the variable with a constant,
> > which is what triggers the test failure.
>
> Well, then it should be the correct constant, and hence be unaffected by
> setjmp/longjmp, so if that still doesn't work the constant is wrong,
> right?
>
> > Are these tests that rely on the value of a non-volatile auto after a
> > longjmp invalid? I can patch them to make the auto variable a global
> > instead.
>
> No, they should work as is.
>
>
> Ciao,
> Michael.


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