Bug 20976

Summary: when terminate is called, stack is not unwinded
Product: gcc Reporter: Christos Kloukinas <C.Kloukinas>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: gcc-bugs, jason, kian.karas.dev
Priority: P2 Keywords: documentation
Version: 3.4.4   
Target Milestone: 4.6.0   
Host: Target:
Build: Known to work: 4.6.0
Known to fail: Last reconfirmed: 2005-07-12 00:06:16
Attachments: The .ii intermediate file (bzip2 compressed) of the testcase I used.
And the testcase itself...

Description Christos Kloukinas 2005-04-12 18:45:33 UTC
Sorry, cannot understand how to attach the different files you ask for or what
the host/target/build triplets are supposed to be (no mention of these in the
how-tos).

The bug: I was under the impression, that if an exception occurs the destructors
of the local objects should be called at some point, even if we don't catch the
exception anywhere.
The behaviour however of g++ (tried it with 3.4.4 and 3.3.5) is different.
It only executes the destructors if the exception is caught somewhere (doesn't
matter if it's rethrown or not).

Platform / Compiler info & test program follow.

Take care & thanks for the great work! :-)
Christos

$ uname -a
Linux adia 2.6.8.1 #1 SMP Tue Oct 5 03:46:19 CEST 2004 i686 GNU/Linux
$
$ g++-3.4 -v -save-temps exceptions.cc -o exceptions
Reading specs from /usr/lib/gcc/i486-linux/3.4.4/specs
Configured with: ../src/configure -v
--enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr
--libexecdir=/usr/lib --with-gxx-include-dir=/usr/include/c++/3.4
--enable-shared --with-system-zlib --enable-nls --without-included-gettext
--program-suffix=-3.4 --enable-__cxa_atexit --enable-libstdcxx-allocator=mt
--enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm
--enable-java-awt=gtk --disable-werror i486-linux
Thread model: posix
gcc version 3.4.4 20041218 (prerelease) (Debian 3.4.3-6)
 /usr/lib/gcc/i486-linux/3.4.4/cc1plus -E -quiet -v -D_GNU_SOURCE exceptions.cc
-mtune=i486 -o exceptions.ii
ignoring nonexistent directory
"/usr/lib/gcc/i486-linux/3.4.4/../../../../i486-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/3.4
 /usr/include/c++/3.4/i486-linux
 /usr/include/c++/3.4/backward
 /usr/local/include
 /usr/lib/gcc/i486-linux/3.4.4/include
 /usr/include
End of search list.
 /usr/lib/gcc/i486-linux/3.4.4/cc1plus -fpreprocessed exceptions.ii -quiet
-dumpbase exceptions.cc -mtune=i486 -auxbase exceptions -version -o exceptions.s
GNU C++ version 3.4.4 20041218 (prerelease) (Debian 3.4.3-6) (i486-linux)
        compiled by GNU C version 3.4.4 20041218 (prerelease) (Debian 3.4.3-6).
GGC heuristics: --param ggc-min-expand=64 --param ggc-min-heapsize=64194
 as -V -Qy --32 -o exceptions.o exceptions.s
GNU assembler version 2.15 (i386-linux) using BFD version 2.15
 /usr/lib/gcc/i486-linux/3.4.4/collect2 --eh-frame-hdr -m elf_i386
-dynamic-linker /lib/ld-linux.so.2 -o exceptions
/usr/lib/gcc/i486-linux/3.4.4/../../../../lib/crt1.o
/usr/lib/gcc/i486-linux/3.4.4/../../../../lib/crti.o
/usr/lib/gcc/i486-linux/3.4.4/crtbegin.o -L/usr/lib/gcc/i486-linux/3.4.4
-L/usr/lib/gcc/i486-linux/3.4.4 -L/usr/lib/gcc/i486-linux/3.4.4/../../../../lib
-L/usr/lib/gcc/i486-linux/3.4.4/../../.. -L/lib/../lib -L/usr/lib/../lib
exceptions.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
/usr/lib/gcc/i486-linux/3.4.4/crtend.o
/usr/lib/gcc/i486-linux/3.4.4/../../../../lib/crtn.o
$ ./exceptions
  Unknown exception
terminate called after throwing an instance of 'B'
Aborted
$


Here's the program (email me for the .ii.bz file - couldn't spot any "attach"
button):

#include <iostream>
using namespace std;
class A {
  public:
   static int last_id;
   int id;
   A();
   virtual ~A();
};
int A::last_id = 0;

A::A() : id(++last_id) {}
A::~A() { cerr << '\t' << id << '\n'; }

// class B : public A {}; // B is a subclass of A
class B {}; // B now has no relationship to A

void f() {
   A a1;
   A a2;

   try {
     throw B();
   } catch (A a) {
     cerr << "  Caught an A : " << a.id << '\n';
   } catch (...) {
     cerr << "  Unknown exception\n";
     throw; // rethrow it
   }
}

int main() {
#ifdef OK
   try {
     f();
   } catch (...) {
     throw;
   }
#else
   f();
   // BUG: Shouldn't it have executed the destructors of a1,a2 (f's local vars)
before exiting???
#endif
   return 0;
}
Comment 1 Christos Kloukinas 2005-04-12 18:48:10 UTC
Created attachment 8612 [details]
The .ii intermediate file (bzip2 compressed) of the testcase I used.
Comment 2 Christos Kloukinas 2005-04-12 18:52:45 UTC
Created attachment 8613 [details]
And the testcase itself...
Comment 3 Andrew Pinski 2005-04-12 19:01:57 UTC
I don't think this is valid as there is no landing pad and it is going to abort anyways.  I have to find this 
in the standard.  ICC has the same behavior.
Comment 4 Andrew Pinski 2005-04-12 19:23:15 UTC
Ok, this is just implemenation defined behavior.
see 15.3 P 9:
If no matching handler is found in a program, the function terminate() is called; whether or not the 
stack is unwound before this call to terminate() is implemenation-defined (15.5.1)

So we define it as not unwinding but we don't document this.

Confirmed for documentation.
Comment 5 Andrew Pinski 2009-05-08 16:21:58 UTC
*** Bug 40066 has been marked as a duplicate of this bug. ***
Comment 6 Jason Merrill 2023-05-22 19:45:43 UTC
The documentation of this implementation-defined behavior was added in 4.6 (r159682).

https://gcc.gnu.org/onlinedocs/gcc/Exception-handling.html