From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.8) Gecko/20050513 Fedora/1.0.4-1.3.1 Firefox/1.0.4 Description of problem: a reference to a volatile object, even in a void context, should cause an access to that object. In gcc4, apparently this is not always the case. "info gcc" node "Volatiles" with title "6.1 When is a Volatile Object Accessed?" clearly says: <<Less obvious expressions are where something which looks like an access is used in a void context. An example would be, volatile int *src = SOMEVALUE; *src; With C, such expressions are rvalues, and as rvalues cause a read of the object, GCC interprets this as a read of the volatile being pointed to.>> This does not match gcc4's behaviour (but earlier gcc versions did follow this rule). Version-Release number of selected component (if applicable): gcc-4.0.0-8 How reproducible: Always Steps to Reproduce: 1. create a file "gccvolopt.c" with the following code: typedef unsigned char CARD8; /* from /usr/include/X11/Xmd.h:150 */ void test(CARD8 *addr) { *(volatile CARD8 *)addr; } 2. Examine the output of: cc -S -O2 gccvolopt.c && cat gccvolopt.s Actual Results: The expression was optimized away: there is no code to fetch *addr Expected Results: There should have been a fetch from *addr Additional info: see also https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=161242 #56 is where the problem was first isolated. This gcc change/bug seems to cause a subtle but serious bug in X. Variations in the sample program cause the fetch to appear or disappear. For example, the expression "*((volatile CARD8 *)addr + 1);" does cause a fetch to happen. Changing the 1 to 0 causes the fetch to disappear again. Adding "volatile" to the parameter definition causes the fetch to appear.
It seems to be a bug when casting to a volatile. Below, the first testcase works whereas the second does not: void test_1 (volatile char *addr) { *addr; } void test_2 (char *addr) { *((volatile char *) addr); }
I posted my testcase on gcc's bugzilla. It seems there is a controversy whether this is a gcc bug or not. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22278
Also related to the following gcc bug (currently closed, IMO wrongly, see comments there): http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21568
There is no point in tracking this here in addition to upstream. Fedora GCC closely follows the upstream tree.
Jakub: This bug causes bug #161242 in Xorg, which has a massive number of duplicates, and prevents users from doing a GUI install, as well as from being able to properly run X after text install. There are 3 options I can think of for fixing this: 1) Wait until a fixed gcc is released for FC4 as an official update. Will there be an official FC4 update to fix this? or 2) Recompile libvgahw.a with -O0 in %install of xorg-x11 after the rest of the build is complete. This would work around this issue too, but it's possible that this gcc bug causes problems in other parts of the X server or tree as well. Recompiling the entire X server with -O0, seems a bad overall solution to avoid a known compiler bug, and might have really bad performance concequences (unknown). or 3) Patch the source for this module to work around the gcc bug. This would work around this one specific problem, but again, might leave other dormant bugs in other parts of the X server which we haven't isolated yet. The impact of this bug is rather large, as can be seen by the list of duplicates closed on bug #161242. I'd just like to get an idea what might be the best path of closure in the short term, as I'm going to be unavailable for 3 weeks starting July 16th. Worst case I think we might go with #2 above if #1 isn't available in time to release an update prior to OLS. TIA
1) it is not really clear whether this is a bug, see PR22278 2) you have not proven in any way this is the cause of the problem you are seeing in libvgahw.a (I have briefly grepped for the use of volatile in that library and have not found anything obvious)
Proof of 2) * libvgahw.a is fixed when only mmioReadAttr() (a 10 line function) is compiled with -O0 * When mmioReadAttr() is compiled with -O0 and line: (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); is commented, then the same bug as initially reported is observed. * When the same line in mmioReadAttr() is patched with: volatile CARD8 tmp; tmp = minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET); Then the bug is fixed when compiling with -O2. * When comparing the code output by gcc -S and gcc -O2 -S, the only difference is that this same line is discarded with -O2. * This line is preprocessed in: (void) *(volatile CARD8 *)(((CARD8*)(hwp->MMIOBase)) + ((hwp->MMIOOffset + (hwp->IOBase + 0x0A)))); And this is clearly a dereference to a cast into a volatile qualifier.
Then surely vgaHWRec's MMIOBase field should be volatile CARD8 * MMIOBase; instead of CARD8 * MMIOBase;
This seems to have been declared to be a GCC bug by the GCC folks. A tentative fix was posted here: http://gcc.gnu.org/ml/gcc/2005-07/msg00733.html
I know.