Bug 14535 - exception throwing in virtual function doesn't turn on the local destructors
Summary: exception throwing in virtual function doesn't turn on the local destructors
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 3.2
: P1 normal
Target Milestone: 3.3.4
Assignee: Richard Henderson
URL:
Keywords: patch, wrong-code
Depends on:
Blocks:
 
Reported: 2004-03-11 14:30 UTC by Lev Assinovsky
Modified: 2004-10-07 23:46 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 2.95.3 3.4.0 4.0.0 3.3.4
Known to fail: 3.2.3
Last reconfirmed: 2004-03-11 16:05:32


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lev Assinovsky 2004-03-11 14:30:03 UTC
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.
Comment 1 Andrew Pinski 2004-03-11 16:05:31 UTC
Confirmed a regression from 2.95.3, it fails with -finline so it is most likely the tree inliner.
Comment 2 Wolfgang Bangerth 2004-03-11 16:19:51 UTC
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. 
Comment 3 Richard Henderson 2004-03-12 09:08:45 UTC
Not the tree inliner, but something in except.c isn't doing the right thing
with the exception specification after the test passes.
Comment 4 Lev Assinovsky 2004-03-12 13:44:03 UTC
The "magic" option -fno-enforce-eh-specs let our applications to work.
So we can live for a while :)
Comment 5 GCC Commits 2004-03-16 00:35:21 UTC
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

Comment 6 Richard Henderson 2004-03-16 00:36:48 UTC
Patch: http://gcc.gnu.org/ml/gcc-patches/2004-03/msg01224.html
Comment 7 Mark Mitchell 2004-03-16 01:29:13 UTC
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.

Comment 8 GCC Commits 2004-03-16 21:05:41 UTC
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

Comment 9 Mark Mitchell 2004-03-17 03:11:59 UTC
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?
Comment 10 GCC Commits 2004-03-17 18:07:37 UTC
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

Comment 11 Richard Henderson 2004-03-17 18:21:15 UTC
Fixed.