Description of problem: compiler generates incorrect code, when compiled with optimization higher than O2 As quoted by customer - Gcc prints no warnings and this is really bad. Even FlexeLint prints warning olny on -w3, i.e. very hight level of warnings though it is a bug from ISO point of view." "Why don't they print a warning/error? How can we fix our legacy code? We even have reinterpret_cast which suppresses warnings about C-style cast. This is a real problem. Do they have such a request already? Absence of warning is a bug. The code was perfectly legal for many years before standards were accepted. It is a change of language without a warning. Must be error or warning. \ "Yes, there supposed to be a warning dereferencing type-punned pointer will break strict-aliasing rules but even with -Wall it is absent." On RHEL 5.1 , this function void CopyData (int **pdst, int **psrc) { *pdst = *psrc; *(int*)pdst |= 0x1; } generates incorrect code if using gcc 4.1.2p2 with optimization -O2 and -O3. It generates mov (%edx),%edx orl $0x1,(%eax) mov %edx,(%eax) where "mov" destroys the result or "orl". With -O1 the order of "orl" and "mov" is reverse. On Solaris 86 the same version of gcc works fine. 64-bit compiler and 32-bit one both work incorrectly in both -m32 and -m64 modes. Main one prints two pointers. They must be different if code is correct and the same if the code is wrong. Version-Release number of selected component (if applicable): gcc 4.1.2p2 This issue is also reproducible on FC9 with gcc 4.3.0 How reproducible: Test case attached. Steps to Reproduce: 1. ./build 2. ./m Actual results: Value prined are the same Expected results: value printed should be different Additional info: Test case attached.
Created attachment 305902 [details] Test case
Eh, this code is invalid even in ISO C90, so at least for 18 years. -Wstrict-aliasing=3 doesn't warn in this case because it would have too many false positives, many programs cast one type of pointer to another and dereference it that way, that in itself is not a bug. The problem is if you are accessing some object using a wrong type. Say int i; void bar (int **p) { *(int *) p |= 1; } void foo (void) { bar ((int **) (void *) &i); } is fine, i is accessed through a compatible type. The documentation for -Wstrict-aliasing clearly states that the warning catches only the most common problems and still it has many false positives too. ISO C doesn't require diagnostics in this case and in many cases aliasing violations are even theoretically impossible to detect, without whole program analysis. If you have legacy code which doesn't honor the aliasing requirements, you can always compile with -fno-strict-aliasing. That is of course a performance penalty, but you can that way postpone legacy code analysis.