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. > 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.