It works with -O0, -O1, -Os but not -O2 (and -O3).
After a bit of playing around I've found the minimal combination of flags to trigger a test failure:
CXXFLAGS="-O1 -fgcse -fschedule-insns -fstrict-aliasing -ftree-vrp"
make clean;
make -j3 CXXFLAGS="${CXXFLAGS}" && (
cd common/test/ &&
rm -f sllisttest &&
make -j3 CXXFLAGS="${CXXFLAGS}" sllisttest &&
./sllisttest
)
Testing ConstIterator
Testing Iterator
Testing Iterator
Test PushPop
Entry should be 1, but is 0! Push back failed! sllisttest.cc:361
sllisttest: ../../dune/common/sllist.hh:752: void Dune::SLList<T, A>::clear() [with T = int, A = Dune::PoolAllocator<int, 8176ul>]: Assertion `size_==0' failed.
If any of the flags -fgcse -fschedule-insns -fstrict-aliasing -ftree-vrp is dropped, the test succeeds
Designs
Child items ...
Show closed items
Linked items 0
Link issues together to show that they're related.
Learn more.
This one is really strange. I could reproduce this using gcc 4.1, 4.2, 4.3. Elias told me that he originally saw it just using O2 instead of this weird set of options, but I cannot confirm this.
I tried to reduce the test case further but I didn't get very far (new test case is attached). Seemingly innocent actions make the bug go away. For example, I can remove the assertion in line 51 (which passes), and the bug goes away. Also, when I replace the list object by direct declaration of its data members, the bug goes away.
I am stuck. The test case is still too long to post it as a gcc bug (it still includes poolallocator.hh). Does someone have an idea how to proceed? The test case does the following:
create an empty list
push_back(1)
push_front(3)
pop_front()
Now the first list item should be 1, but this is not so. Instead, apparently unitialized memory is accessed there. If the PoolAllocator is replaced by std::allocator everything works fine.
The platform is
Linux andorra 2.6.26-2-amd64 #1 (closed) SMP Wed Aug 19 22:33:18 UTC 2009 x86_64 GNU/Linux
While w/ that reduced test case and -O2 (in contrast to you, apparently) I do get a test failure, I do not get a test failure w/ the original set of flags, -O1 -fgcse -fschedule-insns -fstrict-aliasing -ftree-vrp (again, in contrast to you, no). I'll investigate a bit what combination breaks it.
I see two possible ways to proceed. Either we assume that this is a bug in PoolAllocator.
Then we should make the testcase as small as possible without touching PoolAllocator and
try to understand where PoolAllocator fails. Or we assume that it is a bug in the compiler
/toolchain. Then we have to reduce the testcase even further. I don't really know what to
think.
If it is not a compiler bug. Then I would guess that it is most likely that some of the enum calculation in Pool are wrong. (Still I do not understand why the behaviour changes for different compiler flags.
It would be nice if someone with access to to the machine would try the problem with double instead of int and with with a different number as the second template argument (maybe a realy small one).