The following conditions do cause the bug: 1. Optimized compilation (-O1,-O2, -O3) 2. Overriding virtual function is called through the base class pointer or reference 3. Overriding virtual function calls any object method, which has exception specification and throws an exception. 4. Overriding virtual function doesn't have an exception specification. My configuration: uname -a: SunOS dog 5.8 Generic_108529-09 i86pc i386 i86pc gcc -v Reading specs from /opt/AESgcc/lib/gcc-lib/i386-pc-solaris2.8/3.2/specs Configured with: /export/home/Ext/Archive/gcc-3.2/configure -- prefix=/opt/AESgcc --disable-multilib --enable-threads=posix --enable- languages=c,c++ --with-gnu-ld --with-ld=/usr/local/bin/ld --with-gnu-as -with- as=/usr/local/bin/as Thread model: posix gcc version 3.2 Test case: ======= Test case starts #include <iostream> class Raiser { public: Raiser() throw( int ) { throw 1; }; }; class Object { public: virtual ~Object() { std::cout << "~Object()" << std::endl; }; }; class Base { public: virtual ~Base(){}; virtual void Run(){}; }; class FromBase : public Base { public: virtual ~FromBase(){}; virtual void Run() { std::cout << "Derived Run" << std::endl; { Object a; std::cout << "Raise!" << std::endl; Raiser riser; } std::cout << "Unreachable code" << std::endl; }; }; int main() { FromBase a; Base& b = static_cast<Base&>(a); try { b.Run(); std::cout << "Unreach 2" << std::endl; } catch ( int ) { std::cout << "Exception handler" << std::endl; } std::cout << "Exit Main" << std::endl; return 0; } ======= Test case end Compilation: gcc -O1 -o tst tst.cpp Due to the bug the string "~Object()" will not be printed.
Confirmed a regression from 2.95.3, it fails with -finline so it is most likely the tree inliner.
Confirmed indeed. Here is something more selfcontained: --------------------- extern "C" void abort(); bool destructor_called = false; struct B { virtual void Run(){}; }; struct D : public B { virtual void Run() { struct O { ~O() { destructor_called = true; }; } o; struct Raiser { Raiser() throw( int ) {throw 1;}; } raiser; }; }; int main() { try { D d; static_cast<B&>(d).Run(); } catch (...) {} if (!destructor_called) abort (); } ----------------------- g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ x.cc ; ./a.out g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ -finline x.cc ; ./a.out Aborted W.
Not the tree inliner, but something in except.c isn't doing the right thing with the exception specification after the test passes.
The "magic" option -fno-enforce-eh-specs let our applications to work. So we can live for a while :)
Subject: Bug 14535 CVSROOT: /cvs/gcc Module name: gcc Changes by: rth@gcc.gnu.org 2004-03-16 00:35:17 Modified files: gcc : ChangeLog except.c Added files: gcc/testsuite/g++.dg/eh: spec7.C Log message: PR middle-end/14535 * except.c (collect_one_action_chain): Record action for cleanup outer of exception spec. * g++.dg/eh/spec7.C: New. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.3173&r2=2.3174 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/except.c.diff?cvsroot=gcc&r1=1.264&r2=1.265 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/eh/spec7.C.diff?cvsroot=gcc&r1=NONE&r2=1.1
Patch: http://gcc.gnu.org/ml/gcc-patches/2004-03/msg01224.html
Subject: Re: [3.3/3.4 Regression] exception throwing in virtual function doesn't turn on the local destructors rth at gcc dot gnu dot org wrote: > ------- Additional Comments From rth at gcc dot gnu dot org 2004-03-16 00:36 ------- > Patch: http://gcc.gnu.org/ml/gcc-patches/2004-03/msg01224.html > OK for 3.4.0.
Subject: Bug 14535 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: rth@gcc.gnu.org 2004-03-16 21:05:33 Modified files: gcc : ChangeLog except.c Added files: gcc/testsuite/g++.dg/eh: spec7.C Log message: PR middle-end/14535 * except.c (collect_one_action_chain): Create action record for cleanup outer of exception spec. * g++.dg/eh/spec7.C: New. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=2.2326.2.345&r2=2.2326.2.346 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/except.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.256.2.3&r2=1.256.2.4 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/eh/spec7.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1
Richard, does this still fail on the 3.4 branch? I believe that you've fixed it. If so, would you please remove 3.4 from the regression list in the summary and from the known-to-fail list?
Subject: Bug 14535 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_3-branch Changes by: rth@gcc.gnu.org 2004-03-17 18:07:31 Modified files: gcc : ChangeLog except.c Log message: PR middle-end/14535 * except.c (collect_one_action_chain): Record action for cleanup outer of exception spec. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.16114.2.943&r2=1.16114.2.944 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/except.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.233.2.6&r2=1.233.2.7
Fixed.