[gnu.gcc.bug] constant folding bug

drh@notecnirp.Princeton.EDU (Dave Hanson) (02/23/89)

the following legal C program is taken from
the bottom of p. 57 in the 12/7/88 ANSI standard
and elicits an error from gcc.

% cat bug1.c
int x = 2 || 1/0;
% gcc -v -S bug1.c
gcc version 1.33
 /usr/local/gnu/lib/gcc-cpp -v -undef -D__GNUC__ -Dvax -Dunix -D__vax__ -D__unix__ bug1.c /tmp/cc022968.cpp
GNU CPP version 1.33
 /usr/local/gnu/lib/gcc-cc1 /tmp/cc022968.cpp -quiet -dumpbase bug1.c -version -o bug1.s
GNU C version 1.33 (vax) compiled by GNU C version 1.33.
bug1.c:1: divide by 0 in constant folding - quotient and remainder set to 0.

butcher@g.gp.cs.cmu.edu (Lawrence Butcher) (05/11/89)

gcc 1.35 on a 60820 sun running sun unix 3.5.

gcc seems to constant fold differently than several other c compilers in
this funny case.  I can sort of see it either way.  If constants are
considered ints unless otherwise specified, gcc gets this wrong.

main()
{
    if (0xFFFFF000 < 0x00000FFF)	/* If 2's comp, -256 < 255 */
	printf ("(no type)0xFFFFF000 < (no type)0x00000FFF\n");
    else
	printf ("(no type)0xFFFFF000 >= (no type)0x00000FFF\n");

    if (0xFFFFF000L < 0x00000FFFL)	/* If 2's comp, -256 < 255 */
	printf ("0xFFFFF000L < 0x00000FFFL\n");
    else
	printf ("0xFFFFF000L >= 0x00000FFFL\n");

    if ((short)0xFFFFF000 < (short)0x00000FFF)
	printf ("(short)0xFFFFF000 < (short)0x00000FFF\n");
    else
	printf ("(short)0xFFFFF000 >= (short)0x00000FFF\n");

    if ((unsigned)0xFFFFF000 < (unsigned)0x00000FFF)
	printf ("(unsigned)0xFFFFF000 < (unsigned)0x00000FFF\n");
    else
	printf ("(unsigned)0xFFFFF000 >= (unsigned)0x00000FFF\n");

    if ((signed)0xFFFFF000 < (signed)0x00000FFF)
	printf ("(signed)0xFFFFF000 < (signed)0x00000FFF\n");
    else
	printf ("(signed)0xFFFFF000 >= (signed)0x00000FFF\n");

    if ((int)0xFFFFF000 < (int)0x00000FFF)
	printf ("(int)0xFFFFF000 < (int)0x00000FFF\n");
    else
	printf ("(int)0xFFFFF000 >= (int)0x00000FFF\n");

    if ((long)0xFFFFF000 < (long)0x00000FFF)
	printf ("(long)0xFFFFF000 < (long)0x00000FFF\n");
}

results are:

(no type)0xFFFFF000 >= (no type)0x00000FFF     // which I do not expect
0xFFFFF000L >= 0x00000FFFL                     // likewise seems wrong
(short)0xFFFFF000 < (short)0x00000FFF
(unsigned)0xFFFFF000 >= (unsigned)0x00000FFF
(signed)0xFFFFF000 < (signed)0x00000FFF
(int)0xFFFFF000 < (int)0x00000FFF
(long)0xFFFFF000 < (long)0x00000FFF
--