Bug#491137: optimization causes errornous behavior
Package: g++-4.3
Version: 4.3.1-4
[I leave it to the gcc maintainers to judge about the severity, because it
actually breaks otherwise running programs, but those cases seem extremely rare]
When rebuilding diagnostics, it failed on s390 during the selftests [0]. The
failing piece of code is attached. This is not actually a tiny example, but all
attempts of reducing this further failed to reproduce the error. This is a
regression because it does not fail on g++-4.2. The compiler command lines to
reproduce are:
g++ -O -fgcse -DDEBUG__LEVEL__=2 invariance_annotation.t.cpp -ldiagnostics -o invbuggy
./invbuggy run "/*" 2
whereat we would expect to see no failure, instead of a MISSING_EXCEPTION [TES]:
...
Please note that replacing -O by
-fomit-frame-pointer
-fauto-inc-dec
-fcprop-registers
-fdce
-fdefer-pop
-fdelayed-branch
-fdse
-fguess-branch-probability
-fif-conversion2
-fif-conversion
-finline-small-functions
-fipa-pure-const
-fipa-reference
-fmerge-constants
-fsplit-wide-types
-ftree-ccp
-ftree-ch
-ftree-copyrename
-ftree-dce
-ftree-dominator-opts
-ftree-dse
-ftree-fre
-ftree-sra
-ftree-ter
-funit-at-a-time
(all controllable options enabled by -O) does _not_ yield the errornous
behavior, and dropping -fgcse also stops the runtime failure.
Attached please find the cleaned source file. All attempts of reproducing the
error were made on raptor.d.o. If there is anything more that I could do to
debug this issue, please contact me.
Best,
Michael
[0] http://buildd.debian.org/fetch.cgi?&pkg=diagnostics&ver=0.2.2%2Bb1&arch=s39 0&stamp=1214648343&file=log
#include <diagnostics/unittest.hpp>
// component
#include <diagnostics/macros/invariance_annotation.hpp>
#define TEST_COMPONENT_NAME invariance_annotation
#define TEST_COMPONENT_NAMESPACE diagnostics
DIAGNOSTICS_NAMESPACE_BEGIN;
TEST_NAMESPACE_BEGIN;
TEST_COMPONENT_TEST_NAMESPACE_BEGIN;
using namespace unittest;
class Dummy_Class_With_Invariance
{
typedef Dummy_Class_With_Invariance Self;
public:
Dummy_Class_With_Invariance()
: m_class_invariance_called(0),
m_throw(false)
{
}
void method_with_guard(bool const t1,
bool const t2)
{
m_class_invariance_called=0;
m_throw=t1;
::diagnostics::internal::Class_Invariance_Guard_Th row<Self> g(this);
m_throw=t2;
}
void m_class_invariance() const
{
++m_class_invariance_called;
if(m_throw) throw Test_Exception("Invariance throwing");
}
int class_invariance_called() const
{
return m_class_invariance_called;
}
private:
mutable int m_class_invariance_called;
bool m_throw;
};
void guard(Test_Data & data)
{
Dummy_Class_With_Invariance d;
TEST_EXCEPTIONLESS_BLOCK_ENTER;
d.method_with_guard(false,false);
TEST_EXCEPTIONLESS_BLOCK_EXIT;
TEST_ASSERT(d.class_invariance_called()==2);
TEST_THROWING_BLOCK_ENTER;
d.method_with_guard(true,true);
TEST_THROWING_BLOCK_EXIT1(Test_Exception,::std::st ring("Invariance throwing").c_str());
TEST_ASSERT(d.class_invariance_called()==1);
TEST_THROWING_BLOCK_ENTER;
d.method_with_guard(false,true);
TEST_THROWING_BLOCK_EXIT1(Test_Exception,::std::st ring("Invariance throwing").c_str());
TEST_ASSERT(d.class_invariance_called()==2);
}
TEST_COMPONENT_TEST_NAMESPACE_END;
TEST_NAMESPACE_END;
DIAGNOSTICS_NAMESPACE_END;
TEST_SUITE_BEGIN;
TEST_NORMAL_CASE(&guard,LEVEL_PROD);
TEST_SUITE_END;
STREAM_TEST_SYSTEM_MAIN;
// vim:ts=4:sw=4
|