On Tue, Feb 04, 2003 at 05:02:10AM +0200, Marko Kreen wrote: > Package: gcc-3.2 > Version: 1:3.2.2-0pre8 > Severity: normal > > > gcc-3.2 -O2 miscompiles following program: > > --------------------------------------------- > extern int write(int fd, void *buf, int len); > extern int toupper(int c); > > void strupr (char *s) > { > while (*s) > *s++ = toupper(*s); > } > > int main(int argc, char *argv[]) > { > char s[] = "foo"; > strupr(s); > write(1, s, 3); > write(1, "\n", 1); > return 0; > } > > --------------------------------------------- > $ gcc-3.2 -Wall -O2 -o test test.c > test.c: In function `strupr': > test.c:7: warning: operation on `s' may be undefined > $ ./test > OO > $ > --------------------------------------------- > > gcc-2.95 compiles it correctly, also gcc-3.2 when optimizing > less than -O2. When the "toupper(*s)" is replaced with "*s & 0x5f" > gcc-3.2 -O2 also works and without warning.
I think the lack of warning in that case is actually the bug, but I'm not sure. C doesn't guarantee order-of-operation across an equals sign; it's not a sequence point. The function call is a sequence point but it isn't specified which side of the sequence point the increment will happen on. -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer