From: dalibor@immd3.INformatik.uni-erlangen.DE (Stefan Dalibor)
Subject: gcc-2.3.[12] -O -frerun-cse-after-loop broken on sparc
Organization: GNUs Not Usenet
Distribution: gnu
Date: Fri, 11 Dec 1992 19:03:41 GMT

Gcc version: gcc-2.3.1, gcc-2.3.2
    (The program compiled okay with gcc-2.2.2)

Dialect: Traditional and ANSI C

File with source code: See below (at end of message);
    it's not output from `gcc -E' because there are no files
    included and no preprocessor statements used.

Command triggering the error: gcc -O2 prog.c
    The error is triggered by turning on `-frerun-cse-after-loop'-optimization;
	gcc -O2 -fno-rerun-cse-after-loop prog.c
    will produce valid output,
        gcc -O -frerun-cse-after-loop prog.c
    will create the corrupted executable.

Machine and OS version: uname -a reports
    SunOS faui30a 4.1.2 2 sun4c
    (It's SparcStation 1+ / 2)

Configure options: sparc-sun-sunos4.1
    Contents of config.status:
    #!/bin/sh
    # GCC was configured as follows:
    ./configure --target=sparc-sun-sunos4.1
    echo host=sparc-sun-sunos4.1 target=sparc-sun-sunos4.1 build=sparc-sun-sunos4.1

Modifications to compiler source: None, except adaption to local pathnames, i.e.:
    % diff configure-dist configure    
    56c56
    < prefix=/usr/local
    ---
    > prefix=/local

Install procedure: Standard, no errors.

Description of incorrect behaviour:
    If the source code included below is compiled with
    '-O' AND '-frerun-cse-after-loop' optimization turned on, a corrupted
    executable is produced by gcc.
    Function `rangematch' returns `-2' when called with arguments p="[~x]"
    and c='1' (the correct return value would be `3'). Source line no. is 20,
    marked by a comment.

Final remarks:
    Compiling the source-code below should reproduce the error;
    I didn't include output from a debugger-session because that didn't
    give me any useful information (I know nothing about assembler-programming)
    and because the program is rather short and simple (the source code is a
    fragment of rc-1.4, a public available shell by Byron Rakitzis).
    If you need any further information, feel free to e-mail to

         dalibor@immd3.informatik.uni-erlangen.de

    I would also appreciate to hear from you if you don't consider this being
    a compiler bug.
    Hoping that you'll fix it soon (vital program gcc is nowadays!) and
    looking forward to future releases,
    Stefan
    

--Snip--&<--Snip--&<--Snip--&<--Snip--&<--Snip--&<--Snip--&<--Snip--&<--
typedef enum bool {
	FALSE, TRUE
} bool;
enum { RANGE_FAIL = -1, RANGE_ERROR = -2 };

static int rangematch(char *p, char c) {
	char *orig = p;
	bool neg = (*p == '~');
	bool matched = FALSE;
	if (neg)
		p++;
	if (*p == ']') {
		p++;
		matched = (c == ']');
	}
	for (; *p != ']'; p++) {
/* if compiled with '-O -frerun-cse-after-loop', the next expr
   is evaluated `true' erronously (while *p is "x]", not '\0');
   the value of p is changed to 0xfffffffe */
		if (*p == '\0')
			return RANGE_ERROR;
		if (p[1] == '-' && p[2] != ']') {
			if (c >= *p)
				matched |= (c <= p[2]);
			p += 2;
		} else {
			matched |= (*p == c);
		}
	}
	if (matched ^ neg)
		return p - orig + 1;
	else
		return RANGE_FAIL;
}

main()
{
    int ret;
    char *pp = "~x]", c = '1';
    printf("call: rangematch(\"%s\", '%c'), should return: 3\n", pp, c);
    ret = rangematch(pp, c);
    printf("match returned: %d = %s\n", ret, (ret == 3) ? "CORRECT" : "WRONG");
}

Newsgroups: gnu.gcc.bug