From: tiller@solace.me.uiuc.edu (Mike Tiller)
Subject: Possible Bug in gcc-2.3.3
Organization: University of Illinois at Urbana
Distribution: gnu
Date: Sat, 9 Jan 1993 00:06:49 GMT

Possible bug or possible stupidity on my part.  The following
program (the gcc -E output is at the end) compiles and runs
fine without optimization but goes into an infinite loop with
optimization.  My configuration is sparc-sun-sunos4.1 .

Here is the program, basically it just tests how many loops it
can go through before the alarm goes off.  If optimization is
turned on, the signal handling routine DOES get called, but
the loop is optimized so as to ignore the 'done' variable.  As
far as I can tell this is legal C.  Maybe I should make done
'volatile' or something, I don't know that is why I'm posting
this.

#include    <sys/time.h>
#include    <signal.h>
#include    <stdio.h>

int done = 0;

void
init_timer(long sec, long usec)
{
    struct  itimerval   value;

    value.it_interval.tv_sec = 0;
    value.it_interval.tv_usec = 0;
    value.it_value.tv_sec = sec;
    value.it_value.tv_usec = usec;

    setitimer(ITIMER_VIRTUAL, &value, NULL);
}

void
handler(int sig, int code, struct sigcontext *scp, char *addr)
{
    printf("handler called!\n");
    done = 1;
}

int
main(int argc, char **argv)
{
    long    c1,c2;

    signal(SIGVTALRM, handler);

    done = 0; init_timer(2,0);
    for(c1=1;c1<100000 && !done;c1++)
        for(c2=1;c2<100000 && !done;c2++);
    printf("Looping = %ld.%d\n", c1, c2/1000);
}

It goes into an infinite loop because as far as I can tell it doesn't
check done in the loops (it doesn't recognize the possible side effect
of the signal).  Does this violate some ANSI rule?

Thanks, here is the gcc -E output...

# 1 "bug.c"
# 1 "/usr/include/sys/time.h" 1 3
 

 








 




struct timeval {
	long	tv_sec;		 
	long	tv_usec;	 
};

struct timezone {
	int	tz_minuteswest;	 
	int	tz_dsttime;	 
};













 










 









struct	itimerval {
	struct	timeval it_interval;	 
	struct	timeval it_value;	 
};



# 1 "/usr/include/time.h" 1 3
 




# 1 "/usr/local/gnu/lib/gcc-lib/sparc-sun-sunos4.1/2.3.3/include/sys/stdtypes.h" 1 3
 

 










typedef	int		sigset_t;	 

typedef	unsigned int	speed_t;	 
typedef	unsigned long	tcflag_t;	 
typedef	unsigned char	cc_t;		 
typedef	int		pid_t;		 

typedef	unsigned short	mode_t;		 
typedef	short		nlink_t;	 

typedef	long		clock_t;	 
typedef	long		time_t;		 



typedef	int		size_t;		 



typedef int		ptrdiff_t;	 




typedef	unsigned short	wchar_t;	 



# 6 "/usr/include/time.h" 2 3

 


struct	tm {
	int	tm_sec;
	int	tm_min;
	int	tm_hour;
	int	tm_mday;
	int	tm_mon;
	int	tm_year;
	int	tm_wday;
	int	tm_yday;
	int	tm_isdst;
	char	*tm_zone;
	long	tm_gmtoff;
};

extern	struct tm *gmtime(), *localtime();
extern	char *asctime(), *ctime();
extern	void tzset(), tzsetwall();
extern  int dysize();
extern  time_t timelocal(), timegm();


# 67 "/usr/include/sys/time.h" 2 3




# 1 "bug.c" 2

# 1 "/usr/include/signal.h" 1 3
 

 











# 1 "/usr/local/gnu/lib/gcc-lib/sparc-sun-sunos4.1/2.3.3/include/sys/signal.h" 1 3
 

 





 






# 1 "/usr/include/vm/faultcode.h" 1 3
 

 






 



















typedef	int	faultcode_t;	 



# 16 "/usr/local/gnu/lib/gcc-lib/sparc-sun-sunos4.1/2.3.3/include/sys/signal.h" 2 3



 













# 51 "/usr/local/gnu/lib/gcc-lib/sparc-sun-sunos4.1/2.3.3/include/sys/signal.h" 3





 














# 82 "/usr/local/gnu/lib/gcc-lib/sparc-sun-sunos4.1/2.3.3/include/sys/signal.h" 3

# 98 "/usr/local/gnu/lib/gcc-lib/sparc-sun-sunos4.1/2.3.3/include/sys/signal.h" 3












 






 













 




























 





void	(*signal())();
 



void  (*sigset())();
int   sighold();
int   sigrelse();
int   sigignore();



 


struct	sigvec {
	void	(*sv_handler)();	 
	int	sv_mask;		 
	int	sv_flags;		 
};



 











 


struct	sigstack {
	char	*ss_sp;			 
	int	ss_onstack;		 
};

 






struct	sigcontext {
	int	sc_onstack;		 
	int	sc_mask;		 














	int	sc_sp;			 
	int	sc_pc;			 
	int	sc_npc;			 
	int	sc_psr;			 
	int	sc_g1;			 
	int	sc_o0;
	int	sc_wbcnt;		 
	char	*sc_spbuf[31	];  
	int	sc_wbuf[31	][16];  








};




 












 



 







 









 





struct	sigaction {
	void 		(*sa_handler)();
	sigset_t	sa_mask;
	int		sa_flags;
};

 



void	(*signal())();
int	kill( );
int	sigaction( 
);
int	sigaddset( );
int	sigdelset( );
int	sigemptyset( );
int	sigfillset( );
int	sigismember( );
int	sigpending( );
int	sigprocmask( );
int	sigsuspend( );



# 15 "/usr/include/signal.h" 2 3

# 90 "/usr/include/signal.h" 3


# 2 "bug.c" 2

# 1 "/usr/local/gnu/lib/gcc-lib/sparc-sun-sunos4.1/2.3.3/include/stdio.h" 1 3
 




extern	struct	_iobuf {
	int	_cnt;
	unsigned char *_ptr;
	unsigned char *_base;
	int	_bufsiz;
	short	_flag;
	char	_file;		 
} _iob[];








































extern struct _iobuf 	*fopen();
extern struct _iobuf 	*fdopen();
extern struct _iobuf 	*freopen();
extern struct _iobuf 	*popen();
extern struct _iobuf 	*tmpfile();
extern long	ftell();
extern char	*fgets();
extern char	*gets();
extern char	*sprintf();
extern char	*ctermid();
extern char	*cuserid();
extern char	*tempnam();
extern char	*tmpnam();

 
extern	int	printf(char *, ...);
extern	int	fprintf(struct _iobuf  *, char *, ...);






# 3 "bug.c" 2


int	done = 0;

void
init_timer(long sec, long usec)
{
	struct	itimerval	value;

	value.it_interval.tv_sec = 0;
	value.it_interval.tv_usec = 0;
	value.it_value.tv_sec = sec;
	value.it_value.tv_usec = usec;

	setitimer(1 , &value, 0 );
}

void
handler(int sig, int code, struct sigcontext *scp, char *addr)
{
	done = 1;
}

int
main(int argc, char **argv)
{
	long	c1,c2;

	signal(26	, handler);

	done = 0; init_timer(2,0);
	for(c1=1;c1<100000 && !done;c1++)
		for(c2=1;c2<100000 && !done;c2++);
	printf("Looping = %ld.%d\n", c1, c2/1000);
}


Newsgroups: gnu.gcc.bug