Bug 447253 - gcc with optimization higher than -O2 generates wrong code
gcc with optimization higher than -O2 generates wrong code
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: gcc (Show other bugs)
All Linux
low Severity low
: rc
: ---
Assigned To: Jakub Jelinek
Depends On:
  Show dependency treegraph
Reported: 2008-05-19 01:56 EDT by ritz
Modified: 2010-10-22 21:05 EDT (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2008-05-19 04:08:09 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)
Test case (10.00 KB, application/x-tar)
2008-05-19 01:56 EDT, ritz
no flags Details

  None (edit)
Description ritz 2008-05-19 01:56:45 EDT
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.
Comment 1 ritz 2008-05-19 01:56:46 EDT
Created attachment 305902 [details]
Test case
Comment 3 Jakub Jelinek 2008-05-19 04:08:09 EDT
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.
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.

Note You need to log in before you can comment on or make changes to this bug.