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
Created attachment 9600 [details] Original reduced test case Original reduced test case as an attachment.
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).
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
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.
Cannot reproduce on x86_64 either. Seems to be fixed.
(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.