Bug 35140 - wrong result due to -O2 optimization in combination with std::list
Summary: wrong result due to -O2 optimization in combination with std::list
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.1.3
: P3 major
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: alias, wrong-code
Depends on:
Blocks:
 
Reported: 2008-02-08 15:05 UTC by Sebastian Schmitt
Modified: 2008-12-26 16:11 UTC (History)
5 users (show)

See Also:
Host: i486-linux-gnu
Target: i486-linux-gnu
Build: i486-linux-gnu
Known to work: 3.4.6 4.2.1 4.3.0
Known to fail: 4.1.2 4.1.3
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sebastian Schmitt 2008-02-08 15:05:06 UTC
The following program:
//------------------------------------

#include<iostream>
#include<list>

class sample
{
public:
    double criterium;
    sample(double _criterium):criterium(_criterium) {};
}; 


int main(){
  
  std::list<sample > samples;
  samples.push_back(sample(1.));

  double tmp=0.;

  std::list<sample >::iterator i1;
  i1=samples.begin();	
  tmp=(*i1).criterium; 
  // !!!!!!!!!!!!!!!!!!!!!
  // THIS += operation fails
  (*i1).criterium+=2.; 
  //!!!!!!!!!!!!!!!!!!!!!!!!

  std::cout<<"tmp "<<tmp<<" (*i1).criterium "<<(*i1).criterium <<std::endl; 
  
  return 0;
}
#----------------

produces the output

tmp 1 (*i1).criterium 1

when compiled with '-O2' or '-O3'
The right output would be 

tmp 1 (*i1).criterium 3

which occurred if compiled with -O1 or without optimization at all. 
The bug was found with the two versions 4.1.2 and 4.1.3 but NOT 
with 3.4.6 and 4.2.1.

In the following you find the output of the compilation with
 g++  -v -save-temps  -O2 

================================================
System 1:
========

Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --with-tune=i686 --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
 /usr/lib/gcc/i486-linux-gnu/4.1.2/cc1plus -E -quiet -v -D_GNU_SOURCE tst_short.cpp -mtune=i686 -fworking-directory -O2 -fpch-preprocess -o tst_short.ii
ignoring nonexistent directory "/usr/local/include/i486-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../i486-linux-gnu/include"
ignoring nonexistent directory "/usr/include/i486-linux-gnu"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2
 /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/i486-linux-gnu
 /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/backward
 /usr/local/include
 /usr/lib/gcc/i486-linux-gnu/4.1.2/include
 /usr/include
End of search list.
 /usr/lib/gcc/i486-linux-gnu/4.1.2/cc1plus -fpreprocessed tst_short.ii -quiet -dumpbase tst_short.cpp -mtune=i686 -auxbase tst_short -g -O2 -version -o tst_short.s
GNU C++ version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) (i486-linux-gnu)
        compiled by GNU C version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21).
GGC heuristics: --param ggc-min-expand=99 --param ggc-min-heapsize=129483
Compiler executable checksum: 183d42a838ed2b7313bffcb8f2f2fda7
 as -V -Qy -o tst_short.o tst_short.s
GNU assembler version 2.17 (i486-linux-gnu) using BFD version 2.17 Debian GNU/Linux
 /usr/lib/gcc/i486-linux-gnu/4.1.2/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o tst_short_O2 /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../lib/crt1.o /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.1.2/crtbegin.o -L/usr/lib/gcc/i486-linux-gnu/4.1.2 -L/usr/lib/gcc/i486-linux-gnu/4.1.2 -L/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../lib -L/lib/../lib -L/usr/lib/../lib tst_short.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/i486-linux-gnu/4.1.2/crtend.o /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../lib/crtn.o



================================================
System 2:

Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.1.3 --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)
 /usr/lib/gcc/i486-linux-gnu/4.1.3/cc1plus -E -quiet -v -D_GNU_SOURCE tst_short.cpp -mtune=generic -fpch-preprocess -o tst_short.ii
ignoring nonexistent directory "/usr/local/include/i486-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/i486-linux-gnu/4.1.3/../../../../i486-linux-gnu/include"
ignoring nonexistent directory "/usr/include/i486-linux-gnu"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/4.1.3
 /usr/include/c++/4.1.3/i486-linux-gnu
 /usr/include/c++/4.1.3/backward
 /usr/local/include
 /usr/lib/gcc/i486-linux-gnu/4.1.3/include
 /usr/include
End of search list.
 /usr/lib/gcc/i486-linux-gnu/4.1.3/cc1plus -fpreprocessed tst_short.ii -quiet -dumpbase tst_short.cpp -mtune=generic -auxbase tst_short -version -fstack-protector -fstack-protector -o tst_short.s
GNU C++ version 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2) (i486-linux-gnu)
        compiled by GNU C version 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2).
GGC heuristics: --param ggc-min-expand=64 --param ggc-min-heapsize=64316
Compiler executable checksum: 3cc47be363985179cfafdceddd0e8f5d
 as --traditional-format -V -Qy -o tst_short.o tst_short.s
GNU assembler version 2.18 (i486-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.18
 /usr/lib/gcc/i486-linux-gnu/4.1.3/collect2 --eh-frame-hdr -m elf_i386 --hash-style=both -dynamic-linker /lib/ld-linux.so.2 -o tst_short /usr/lib/gcc/i486-linux-gnu/4.1.3/../../../../lib/crt1.o /usr/lib/gcc/i486-linux-gnu/4.1.3/../../../../lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.1.3/crtbegin.o -L/usr/lib/gcc/i486-linux-gnu/4.1.3 -L/usr/lib/gcc/i486-linux-gnu/4.1.3 -L/usr/lib/gcc/i486-linux-gnu/4.1.3/../../../../lib -L/lib/../lib -L/usr/lib/../lib tst_short.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/i486-linux-gnu/4.1.3/crtend.o /usr/lib/gcc/i486-linux-gnu/4.1.3/../../../../lib/crtn.o
Comment 1 Sebastian Schmitt 2008-02-08 15:28:42 UTC
replacing all doubles types with size_t or int does change nothing.
the bug still exists.
Comment 2 Richard Biener 2008-02-08 16:07:07 UTC
This is possibly a dup of one of the various alias problems of gcc 4.1.
-fno-strict-aliasing is a workaround.
Comment 3 Sebastian Schmitt 2008-02-08 16:32:30 UTC
One can even omit the helper class sample and directly use a list<size_t >,
bug is still there!!! 

the above mentioned work-around with -fno-strict-aliasing works, 
but still...

makes my kinda nervous about all my codes...

Comment 4 Wolfgang Bangerth 2008-02-08 21:59:46 UTC
Can this be reproduced with gcc 4.2.x or current mainline?
Comment 5 Richard Biener 2008-02-08 22:20:42 UTC
Not with this testcase.
Comment 6 Sebastian Schmitt 2008-02-20 14:42:45 UTC
The bug is not encountered when using the list<> container 
from the stlport-library instead of the one coming with the 
compiler. I tried the versions 4.6, 5.0, and 5.1 
(debian-etch packages libstlport4.6-dev,libstlport5.0-dev,
libstlport5.1-dev) and everything worked fine.

Hope that helps, sebastian

ps: is there any chance this bug is sorted out any time soon, 
or should i switch to a different compiler-version alltogether?
Comment 7 Richard Biener 2008-02-20 14:47:35 UTC
We should probably admit that we will not fix this bug for GCC 4.1 (there will
be no further release off that branch).  A workaround is to use -fno-strict-aliasing.

Please consider moving to GCC 4.2.x or 4.3.x once it is released.
Comment 8 Thomas Koenig 2008-12-26 16:11:02 UTC
Works with current trunk, 4.1 is no longer maintained.

Closing.