This is the mail archive of the gcc-bugs@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]

Re: Illegal optimization in presence of setjmp



|>	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;
}


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