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]

c++/2926: gcc 2.95.2 with -O3 makes a bad short to int assignment



>Number:         2926
>Category:       c++
>Synopsis:       gcc 2.95.2 with -O3 makes a bad short to int assignment
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Thu May 24 08:26:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Dmitry Sagalovskiy
>Release:        gcc version 2.95.2 19991024 (release)
>Organization:
>Environment:
sparc-sun-solaris2.6
SunOS dmitrysun 5.6 Generic_105181-23 sun4u sparc SUNW,Ultra-5_10
>Description:
    In the attached code, I have a variable of type int, to which I assign the result of a call of an inline function, which returns an unsigned short. The problem is that the resulting value of the int is bigger than the largest possible value for an unsigned short.

    This problem only seems to occur when I compile with -O3 optimization, it doesn't happen with -O2 or with "-O1 -finline-functions". (So the result of running the program depends on whether -O3 or -O2 optimization was used, that's why I am pretty sure it's a compiler bug.) The problem doesn't happen with gcc 2.7.2.3 when I tried it. It is also very sensitive to the code I have, i.e. removing some seemingly irrelevant variables or even changing a seemingly unrelated function from virtual to plain will make this behavious disappear.
    
    I apologize for the lack of meaningfulness of the code. I pruned it down quite a bit, and had to change and rearrange things to simplify the code while preserving the strange behavior.

    Seeing how the bug is unstable, it's not hard to change something so that it doesn't show up, but this way of fixing things just isn't satisfying :)

    Thanks a lot, I would really appreciate any insight on this problem.

    Dmitry
>How-To-Repeat:
g++ -o bugtest -O3 -g -Wall bugtest.cpp
./bugtest
[compare to the results when compile with -O2, for example]
>Fix:
Don't use -O3 optimization?
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="bugtest.ii"
Content-Disposition: inline; filename="bugtest.ii"

# 1 "bugtest.cpp"
# 1 "/usr/include/stdio.h" 1 3 4
 
 

 
 
 

 






#pragma ident	"@(#)stdio.h	1.49	97/05/09 SMI"	

# 1 "/usr/include/sys/feature_tests.h" 1 3 4
 
 

 
 
 




#pragma ident	"@(#)feature_tests.h	1.13	97/06/26 SMI"


extern "C" {


 











 







































 
















 

















 





















}



# 17 "/usr/include/stdio.h" 2 3 4

# 1 "/usr/include/sys/va_list.h" 1 3 4
 







#pragma ident	"@(#)va_list.h	1.6	96/01/26 SMI"

 










extern "C" {


# 41 "/usr/include/sys/va_list.h" 3 4



typedef void *__va_list;







}



# 18 "/usr/include/stdio.h" 2 3 4


 








extern "C" {




typedef unsigned int	size_t;



 





typedef	long long	__longlong_t;













typedef long		off_t;




typedef __longlong_t	off64_t;





typedef long		fpos_t;




typedef __longlong_t	fpos64_t;








 










 



















# 122 "/usr/include/stdio.h" 3 4




















































typedef struct	 
{




	int		_cnt;	 
	unsigned char	*_ptr;	 

	unsigned char	*_base;	 
	unsigned char	_flag;	 
	unsigned char	_file;	 
} FILE;


extern FILE		__iob[20 ];



extern FILE		*_lastbuf;
extern unsigned char	*_bufendtab[];

extern unsigned char	 _sibuf[], _sobuf[];


 
# 222 "/usr/include/stdio.h" 3 4




extern int	remove(const char *);
extern int	rename(const char *, const char *);
extern FILE	*tmpfile(void);
extern char	*tmpnam(char *);



extern int	fclose(FILE *);
extern int	fflush(FILE *);
extern FILE	*fopen(const char *, const char *);
extern FILE	*freopen(const char *, const char *, FILE *);
extern void	setbuf(FILE *, char *);


extern void setbuffer(FILE *, char *, size_t);
extern int setlinebuf(FILE *);

extern int	setvbuf(FILE *, char *, int, size_t);
 
extern int	fprintf(FILE *, const char *, ...);
 
extern int	fscanf(FILE *, const char *, ...);
 
extern int	printf(const char *, ...);
 
extern int	scanf(const char *, ...);


 
extern int	snprintf(char *, size_t, const char *, ...);

 
extern int	sprintf(char *, const char *, ...);
 
extern int	sscanf(const char *, const char *, ...);
extern int	vfprintf(FILE *, const char *, __va_list);
extern int	vprintf(const char *, __va_list);


extern int	vsnprintf(char *, size_t, const char *, __va_list);

extern int	vsprintf(char *, const char *, __va_list);
extern int	fgetc(FILE *);
extern char	*fgets(char *, int, FILE *);
extern int	fputc(int, FILE *);
extern int	fputs(const char *, FILE *);
extern int	getc(FILE *);
extern int	getchar(void);
extern char	*gets(char *);
extern int	putc(int, FILE *);
extern int	putchar(int);
extern int	puts(const char *);
extern int	ungetc(int, FILE *);
extern size_t	fread(void *, size_t, size_t, FILE *);
extern size_t	fwrite(const void *, size_t, size_t, FILE *);
extern int	fgetpos(FILE *, fpos_t *);
extern int	fseek(FILE *, long, int);
extern int	fsetpos(FILE *, const fpos_t *);
extern long	ftell(FILE *);
extern void	rewind(FILE *);
extern void	clearerr(FILE *);
extern int	feof(FILE *);
extern int	ferror(FILE *);
extern void	perror(const char *);

extern int	__filbuf(FILE *);
extern int	__flsbuf(int, FILE *);

 





extern FILE	*fdopen(int, const char *);
extern char	*ctermid(char *);
extern int	fileno(FILE *);



 


# 319 "/usr/include/stdio.h" 3 4


 




extern FILE	*popen(const char *, const char *);
extern char	*cuserid(char *);
extern char	*tempnam(const char *, const char *);
extern int	getopt(int, char *const *, const char *);

extern int	getsubopt(char **, char *const *, char **);

extern char	*optarg;
extern int	optind, opterr, optopt;
extern int	getw(FILE *);
extern int	putw(int, FILE *);
extern int	pclose(FILE *);



 



extern int	fseeko(FILE *, off_t, int);
extern off_t	ftello(FILE *);


 





extern FILE	*fopen64(const char *, const char *);
extern FILE	*freopen64(const char *, const char *, FILE *);
extern FILE	*tmpfile64(void);
extern int	fgetpos64(FILE *, fpos64_t *);
extern int	fsetpos64(FILE *, const fpos64_t *);
extern int	fseeko64(FILE *, off64_t, int);
extern off64_t	ftello64(FILE *);


# 467 "/usr/include/stdio.h" 3 4



























# 515 "/usr/include/stdio.h" 3 4





}



# 1 "bugtest.cpp" 2

# 1 "/usr/include/string.h" 1 3 4
 
 

 
 
 

 








#pragma ident	"@(#)string.h	1.19	96/03/12 SMI"	




extern "C" {













extern void *memcpy(void *, const void *, size_t);
extern void *memmove(void *, const void *, size_t);
extern char *strcpy(char *, const char *);
extern char *strncpy(char *, const char *, size_t);

extern char *strcat(char *, const char *);
extern char *strncat(char *, const char *, size_t);

extern int memcmp(const void *, const void *, size_t);
extern int strcmp(const char *, const char *);
extern int strcoll(const char *, const char *);
extern int strncmp(const char *, const char *, size_t);
extern size_t strxfrm(char *, const char *, size_t);

extern void *memchr(const void *, int, size_t);
extern char *strchr(const char *, int);
extern size_t strcspn(const char *, const char *);
extern char *strpbrk(const char *, const char *);
extern char *strrchr(const char *, int);
extern size_t strspn(const char *, const char *);
extern char *strstr(const char *, const char *);
extern char *strtok(char *, const char *);




extern void *memset(void *, int, size_t);
extern char *strerror(int);
extern size_t strlen(const char *);



extern void *memccpy(void *, const void *, int, size_t);




extern char *strsignal(int);
extern int ffs(int);
extern int strcasecmp(const char *, const char *);
extern int strncasecmp(const char *, const char *, size_t);





extern char *strdup(const char *);


# 136 "/usr/include/string.h" 3 4



}



# 2 "bugtest.cpp" 2


 

 
static const int Byte1Mask = 0x000000ff;
static const int Byte2Mask = 0x0000ff00;

inline void reverseInPlace(unsigned short *pval) {
    unsigned int ret, val = *pval;
     
    ret = ((val & Byte2Mask) >> 8);
    ret |= ((val & Byte1Mask) << 8);
    *pval = ret;
}

 

struct Buffer {
    union {
	char buffer[80];
	long _aligndummy;
    };

    virtual int read(void *buf, int len)
	{ memcpy(buf, buffer, len); return len; }
};

 

unsigned short getMsgSize(const char* msgbuf, bool reversed) {
     
    unsigned short size = *(const unsigned short*)msgbuf;
    if(reversed) reverseInPlace(&size);
    return size;
}

const int BIGGER_THAN_SHORT = 65536;

void readMessage(Buffer &s, char *buffer, bool reversed)
{
    int numDone, numToRead;
    char *ptr = buffer;
	
    numToRead = 4;
    while(numToRead > 0 && (numDone = s.read(ptr, numToRead)) > 0) {
	numToRead -= numDone;
	ptr += numDone;
    }
    if(numToRead > 0) return;      
    
    numToRead = getMsgSize(buffer, reversed);
    numToRead = getMsgSize(buffer, reversed);

     
    if(numToRead > BIGGER_THAN_SHORT) {
	printf("ERROR: numToRead = %d is bigger than %d\n",
		numToRead, BIGGER_THAN_SHORT);
    }
    printf("numToRead = 0x%X, should be 0x%X\n", numToRead,
	    (unsigned short)numToRead);
}

 

int main()
{
    char buffer[80];
    Buffer bsock;

    bsock.buffer[0] = 0x0A;
    bsock.buffer[1] = 0x00;
    bsock.buffer[2] = 0x00;
    bsock.buffer[3] = 0x00;

    readMessage(bsock, buffer, true);
}


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