Bug 53407

Summary: incorrect inline optimization
Product: [Retired] Red Hat Linux Reporter: Hui Huang <hui.huang>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact: Brian Brock <bbrock>
Severity: high Docs Contact:
Priority: medium    
Version: 7.1   
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2001-09-08 01:21:50 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Description Hui Huang 2001-09-08 01:21:46 UTC
From Bugzilla Helper:
User-Agent: Mozilla/4.72 [en] (X11; U; Linux 2.2.14-5.0 i686)

Description of problem:
Incorrect code is generated when the following program
is compiled with -O2 or -O3, it seems the assignment
is optimized out:

#include <stdio.h>

typedef long long jlong;

int * _value;
int   _size;

jlong ar[100];

inline void put_int2r(int *from, int *to)
  *(to++) = from[1];
  *(to  ) = from[0];

inline void put_int2r(int *from, int *to, int& pos)
  put_int2r(from, to + pos); pos += 2;

void put_long(jlong from, int *to, int& pos)
  put_int2r((int *)&from, to, pos);

void push_long(jlong l)
  put_long(l, _value, _size);

void main(void)
  _size = 0;
  _value= (int *)ar;
  puts("This test program is to show a g++ compiler bug.");
  puts("The correct output should be '12345678,9abcdef0'");
  puts("But if you compile this program with '-O2' or '-O3',");
  puts("it will print wrong numbers.");

  printf("%x,%x\n", _value[0], _value[1]);

Version-Release number of selected component (if applicable):
2.96, 3.0.1

How reproducible:

Steps to Reproduce:
1. g++ -O2 tstputlong.cpp
2. a.out

Actual Results:  

Expected Results:  

Additional info:

1. "-O" can generate correct result
2. We have tested gcc 2.96-81, 2.96-95 and 3.0.1, all broken.
   3.0.1 can't even compile this program with "-O0".
3. This bug can cause JDK crash since trash value is returned
   when we try to retrieve a previously stored pointer.

Comment 1 Jakub Jelinek 2001-09-08 07:44:13 UTC
Your program has undefined behaviour, so compiler is free to do
whatever it wants.
Particularly you're doing invalid type punning.
Read info gcc, description of -fstrict-aliasing.
If you don't want to fix your code, the quick way around is
using -fno-strict-aliasing, but far better is fixing the code,
e.g. using unions.

Comment 2 Hui Huang 2001-09-10 09:47:04 UTC
Fine, and thank you very much for the pointer. But why can't gcc print a 
warning or something? It's not so uncommon to typecast pointers, is it? 
Besides, most people are not familiar with vague gcc options as 
-fstrict-aliasing. Yet it can cause very hard to track crashes. Note 
that this option is not even listed in the man page! Something needs to be 
done instead of just closing the bug, IMHO.

Comment 3 Jakub Jelinek 2001-09-10 10:13:25 UTC
Plase search http://gcc.gnu.org/ml/gcc for strict-aliasing, you'll find there
a lot about why is it the default, also discussions about warnings, etc.
The man page for gcc is not the definite gcc documentation, unlike info gcc
(that's common with other GNU packages), and actually it is not that important
to list -fstrict-aliasing since it is the default at -O2 and above.
This option has been the default in gcc 2.95 but was turned off before
2.95.2 was released because too many people moaned about unfixed software.
The output of this was that there were several broken packages when we started
working on 7.0 which we had to fix. Making the option the default is the only
way how to make sure people fix their software.
We have fixed all sources included in our distribution for aliasing problems,
but we cannot fix JDK for you (unless you make it open source which would be
a good thing IMHO).
Also note that gcc 3.0 and above have -fstrict-aliasing as default too, so this
is not something Red Hat specific.
In the strict-aliasing discussions on gcc@gcc.gnu.org and other gcc mailing
lists you can find e.g. grep patterns for searching for possibly dangerous
code. And gcc is not definitely the only compiler out there which uses
this optimization.