This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: Illegal optimization in presence of setjmp
- To: rearnsha at arm dot com
- Subject: Re: Illegal optimization in presence of setjmp
- From: Luc Bouge <bouge at ens-lyon dot fr>
- Date: Mon, 8 Jan 2001 18:41:02 +0100 (MET)
- Cc: gcc-bugs at gcc dot gnu dot org, Luc dot Bouge at ens-lyon dot fr
- Reply-To: Luc Bouge <bouge at ens-lyon dot fr>
|> You need to declare 'i' volatile, otherwise it will be held in a register
|> that is restored by the longjump.
You are right, of course, but I believe that the compiler *should* issue a warning.
In my manual page, this is specified explicitely:
-W Print extra warning messages for these events:
o A nonvolatile automatic variable might be changed by a
call to longjmp. These warnings are possible only in
optimizing compilation.
Actually, it does in some cases, and I cannot find any easy rule
to predict these cases. For instance, I considered using two variables
instead of one as in the modified program below.
(1) If the second variable (j) is declared as "volatile" and not the first one (i),
then I get a warning concerning the non-volatile variable, which I feel is right.
Amazingly enough, the ouput of the program is nevertheless correct:
variable i is not clobbered in spite of the warning!
int i;
volatile int j;
ravel% gcc -O4 -Wall bug.c -o bug ; ./bug
bug.c: In function `main':
bug.c:16: warning: variable `i' might be clobbered by `longjmp' or `vfork'
Test 1: i=0, j=0
Test 2: i=1, j=1
Test 3: i=1, j=1
(2) If the first one (i) is declared as volatile, and not the second one (j), then
I get no warning at all. The semantics of the program is silently altered and j
is clobbered.
volatile int i;
int j;
ravel% gcc -O4 -Wall bug.c -o bug ; ./bug
Test 1: i=0, j=0
Test 2: i=1, j=1
Test 3: i=1, j=0
(3) If none are declared as volatile, there is no warning either, and
both variables are clobbered.
int i;
int j;
ravel% gcc -O4 -W bug.c -o bug ; ./bug
Test 1: i=0, j=0
Test 2: i=1, j=1
Test 3: i=0, j=0
My intuitive feeling is that the compiler **should** issue a warning as
soon as it applies an optimization whose correctness is not guaranteed,
as in case (1). As a programmer, I guess I expect the semantics of my
program be invariant with respect to the level of optimization.
Moreover, as far as I can see, the roles of i and j are symetric in the
program. Why does the compiler issue a warning in case (1) and not in case
(2)?
Thank you for your attention,
Luc.
__________________________________________________________________________
#include <stddef.h>
#include <stdio.h>
#include <setjmp.h>
#define TEST(n, i, j) \
fprintf (stderr, "Test %d: i=%d, j=%d\n", n, i, j);
static sigjmp_buf context;
int
main ()
{
/* volatile */ int i;
/* volatile */ int j;
i = j = 0;
TEST (1, i, j);
if (setjmp (context) == 0)
{
i = j= 1;
TEST (2, i, j);
longjmp (context, 1);
}
else
TEST (3, i, j);
return 0;
}