[Bug c++/23599] New: Flag -fstrict-aliasing corrupts iterators
leopardi at bigpond dot net dot au
gcc-bugzilla@gcc.gnu.org
Sun Aug 28 01:37:00 GMT 2005
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
--
Summary: Flag -fstrict-aliasing corrupts iterators
Product: gcc
Version: 4.0.1
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: leopardi at bigpond dot net dot au
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: x86_64-suse-linux
GCC host triplet: x86_64-suse-linux
GCC target triplet: x86_64-suse-linux
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23599
More information about the Gcc-bugs
mailing list