Bug 23599 - [4.0 Regression] Flag -fstrict-aliasing corrupts iterators
Summary: [4.0 Regression] Flag -fstrict-aliasing corrupts iterators
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.0.1
: P2 normal
Target Milestone: 4.0.2
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2005-08-28 01:33 UTC by Paul Leopardi
Modified: 2005-08-29 13:19 UTC (History)
1 user (show)

See Also:
Host: x86_64-suse-linux
Target: x86_64-suse-linux
Build: x86_64-suse-linux
Known to work: 3.3.5 4.1.0
Known to fail: 4.0.1
Last reconfirmed:


Attachments
Original reduced test case (859 bytes, text/plain)
2005-08-28 01:37 UTC, Paul Leopardi
Details
Reduced preprocessed test case (4.07 KB, text/plain)
2005-08-28 01:47 UTC, Paul Leopardi
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Leopardi 2005-08-28 01:33:47 UTC
Compiling the test case with -O3 or -O3 -fstrict-aliasing causes operator++ on 
a const_iterator to fail to progress. Error occurs with 4.0.1, 4.0.2 20050728 
(prerelease), but not with 3.3.5 or 4.1.0 20050813 (experimental). 
 
I believe this to be a compiler bug rather than a library bug because error 
occurs with 4.0.1 but does not occur with 3.3.5 using reduced preprocessed test 
case. 
 
Original test case (reduced using delta to the smallest test case I can find) 
 
test-case.cpp: 
#include <bitset> 
#include <ext/hash_map> 
 typedef short index_t; 
 const index_t BITS_PER_SET_VALUE = std::numeric_limits<unsigned char>::digits 
* index_t(sizeof(unsigned long)); 
 const index_t DEFAULT_LO = -index_t(BITS_PER_SET_VALUE / 2); 
 class index_set : private std::bitset<BITS_PER_SET_VALUE> { 
 private: typedef std::bitset<BITS_PER_SET_VALUE> bitset_t; 
 public: 
 index_set(const bitset_t& bst) { *this = *static_cast<const 
index_set*>(&bst); } 
 index_set(const index_t& idx)  { this->set(idx); } 
 bool operator== (const index_set& rhs) const; 
 index_set& operator&= (const index_set& rhs);  
 index_set& set(index_t idx); 
 size_t hash_fn() const; 
 }; 
 inline index_set& index_set::operator&= (const index_set& rhs)  
  { bitset_t* pthis = this; const bitset_t* pthat = &rhs; *pthis &= *pthat; 
return *this; } 
 inline bool index_set::operator== (const index_set& rhs) const  
  { const bitset_t* pthis = this; const bitset_t* pthat = &rhs; return *pthis 
== *pthat; } 
 inline const index_set operator& (const index_set& lhs, const index_set& rhs)  
  { index_set result = lhs; return result &= rhs; } 
 inline index_set& index_set::set(index_t idx)  
  { if (idx > 0) bitset_t::set(idx-DEFAULT_LO-1); return *this; } 
 inline size_t index_set::hash_fn() const { 
 static const index_set lo_mask = bitset_t((1UL << -DEFAULT_LO) - 1); 
 const index_set neg_part = *this & lo_mask; 
 const index_set pos_part = *this >> -DEFAULT_LO; 
 const bitset_t* pneg_part = &neg_part; 
 const bitset_t* ppos_part = &pos_part; 
 return size_t((*pneg_part).to_ulong() ^ (*ppos_part).to_ulong()); 
 } 
 class hash { 
 public: inline size_t operator()(index_set val) const { return 
val.hash_fn(); } 
 }; 
 class framed_multi : private __gnu_cxx::hash_map< const index_set, double, 
hash > { 
 public: typedef std::pair< const index_set, double > pair_t; 
 framed_multi(const index_set& ist, const double& crd) 
  { if (crd != double(0)) this->insert(pair_t(ist, crd)); } 
 framed_multi& operator+= (const framed_multi& rhs) 
 { 
  for (const_iterator this_it = this->begin(); this_it != this->end(); 
++this_it) { const_iterator next_it = this_it; next_it++; if (this_it == 
next_it) exit(1); } 
  for (const_iterator rhs_it = rhs.begin(); rhs_it != rhs.end(); ++rhs_it) 
{ const_iterator next_it = rhs_it; next_it++; if (rhs_it == next_it) exit(1); } 
  return *this; 
 } 
 }; 
 framed_multi operator+ (const framed_multi & lhs, const framed_multi & rhs)  
  { framed_multi result = lhs; return result += rhs; } 
 int main() { 
 framed_multi OP = framed_multi(index_set(1),4.0) +  
framed_multi(index_set(2),3.0); 
 } 
 
Compiled using: 
./compile-strict-gcc-3XX.sh: 
$CXX -Werror -Wstrict-aliasing -Wall -ansi -g3 -O3 -fno-check-new 
-fabi-version=0 -fexceptions -fstrict-aliasing $1 -o test01-strict 
./compile-nostrict-gcc-3XX.sh: 
$CXX -Werror -Wstrict-aliasing -Wall -ansi -g3 -O3 -fno-check-new 
-fabi-version=0 -fexceptions -fno-strict-aliasing $1 -o test01-nostrict 
 
Transcript: 
> . ~/.bashrc 
> $CXX -v 
Reading specs from /usr/lib64/gcc-lib/x86_64-suse-linux/3.3.5/specs 
Configured with: ../configure --enable-threads=posix --prefix=/usr 
--with-local-prefix=/usr/local --infodir=/usr/share/info 
--mandir=/usr/share/man --enable-languages=c,c++,f77,objc,java,ada 
--disable-checking --libdir=/usr/lib64 --enable-libgcj --with-slibdir=/lib64 
--with-system-zlib --enable-shared --enable-__cxa_atexit x86_64-suse-linux 
Thread model: posix 
gcc version 3.3.5 20050117 (prerelease) (SUSE Linux) 
> ./compile-strict-gcc-3XX.sh test-case.cpp 
> ./test01-strict 
> echo $? 
0 
> ./compile-nostrict-gcc-3XX.sh test-case.cpp 
> ./test01-nostrict 
> echo $? 
0 
> . ~/.bashrc 
> $CXX -v 
Using built-in specs. 
Target: x86_64-suse-linux 
Configured with: ../gcc-4.0.1/configure --prefix=/usr/local/gcc/gcc-4.0.1 
--enable-threads=posix --disable-libgcj --with-system-zlib --enable-shared 
--enable-__cxa_atexit --enable-languages=c,c++ x86_64-suse-linux 
Thread model: posix 
gcc version 4.0.1 
> ./compile-strict-gcc-3XX.sh test-case.cpp 
> ./test01-strict 
> echo $? 
1 
> ./compile-nostrict-gcc-3XX.sh test-case.cpp 
> ./test01-nostrict 
> echo $? 
0 
> . ~/.bashrc 
> $CXX -v 
Using built-in specs. 
Target: x86_64-suse-linux 
Configured with: ../gcc-4.0-20050728/configure 
--prefix=/usr/local/gcc/gcc-4.0-20050728 --enable-threads=posix 
--disable-libgcj --with-system-zlib --enable-shared --enable-__cxa_atexit 
--enable-languages=c,c++ x86_64-suse-linux 
Thread model: posix 
gcc version 4.0.2 20050728 (prerelease) 
> ./compile-strict-gcc-3XX.sh test-case.cpp 
> ./test01-strict 
> echo $? 
1 
> ./compile-nostrict-gcc-3XX.sh test-case.cpp 
> ./test01-nostrict 
> echo $? 
0 
> . ~/.bashrc 
> $CXX -v 
Using built-in specs. 
Target: x86_64-suse-linux 
Configured with: ../gcc-4.1-20050813/configure 
--prefix=/usr/local/gcc/gcc-4.1-20050813 --enable-threads=posix 
--disable-libgcj --with-system-zlib --enable-shared --enable-__cxa_atexit 
--enable-languages=c,c++ x86_64-suse-linux 
Thread model: posix 
gcc version 4.1.0 20050813 (experimental) 
> ./compile-strict-gcc-3XX.sh test-case.cpp 
> ./test01-strict 
> echo $? 
0 
> ./compile-nostrict-gcc-3XX.sh test-case.cpp 
> ./test01-nostrict 
> echo $? 
0
Comment 1 Paul Leopardi 2005-08-28 01:37:36 UTC
Created attachment 9600 [details]
Original reduced test case

Original reduced test case as an attachment.
Comment 2 Paul Leopardi 2005-08-28 01:47:03 UTC
Created attachment 9601 [details]
Reduced preprocessed test case

Preprocessed using 4.0.1. Works with 3.3.5. Fails with 4.0.1, 4.0.2 20050728
(prerelease). Does not link with 4.1.0 20050813 (experimental).
Comment 3 Paul Leopardi 2005-08-28 03:36:33 UTC
A short history of this bug: 
This bug was originally discussed on gcc-help in May: 
g++ 4.0.0: hash_map hangs when compiled with -O3 on AMD64 
http://gcc.gnu.org/ml/gcc-help/2005-05/msg00030.html 
http://gcc.gnu.org/ml/gcc-help/2005-05/msg00087.html 
 
I then asked for help in creating a small test case: 
Need help creating a small test case for g++ 4.0.0 bug 
http://gcc.gnu.org/ml/gcc/2005-05/msg00662.html 
http://gcc.gnu.org/ml/gcc/2005-08/msg00108.html 
Dan Kegel suggested that I use delta: 
http://gcc.gnu.org/ml/gcc/2005-08/msg00110.html 
 
Comment 4 Richard Biener 2005-08-28 08:11:51 UTC
Works on powerpc-unknown-linux-gnu and i686-pc-linux-gnu with g++-4.0 (GCC)
4.0.2 20050821 (prerelease) (Debian 4.0.1-6).

Can you try reproducing with a recent snapshot from the 4.0 branch?  This may
still be x86_64 specific, thanks.
Comment 5 Richard Biener 2005-08-29 09:29:25 UTC
Cannot reproduce on x86_64 either.  Seems to be fixed.
Comment 6 Paul Leopardi 2005-08-29 13:19:50 UTC
(In reply to comment #5)   
> Cannot reproduce on x86_64 either.  Seems to be fixed.   
   
Agree. I have now also tested with gcc version 4.0.2 20050825 (prerelease) and   
the bug no longer occurs.   
 
Some change since gcc version 4.0.2 20050728 (prerelease) must have fixed this  
bug.  
 
Is it possible for anyone to test with 4.0.1 or 4.0.2 20050728 (prerelease) to  
verify that this bug really existed, or is this a waste of time?  
 
This bug may be a dup of PR 23192 which was fixed 2005-08-02 by Diego Novillo.