https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65344
Bug ID: 65344 Summary: Exception is not catched on AIX - class with more ancestors, virtual method throws Product: gcc Version: 4.8.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: jezz at hkfree dot org Created attachment 34983 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=34983&action=edit Sources for reproducing In my program exception is not catched, when it is compiled with gcc newer than 4.4 (4.2.4 & 4.4.7 works). I have created sample (sample with Makefile in in attachment). I have tested the sample with 4.5.4 and 4.8.3 - both fails. All compilers are from http://www.perzl.org/aix/index.php?n=Main.Gcc This is output from sample compiled with 4.4.7: ./main Case 1: Case 2: (Class*)ThrowingClass=0x0x200013b8 (DoThrowIface*)this=0x0x200013bc (DoThrowIface*)ThrowingClass=0x0x200013bc Called doThrow. Thrown && catched BaseException. End. This is output from sample compiled with 4.8.3: ./main Case 1: Case 2: (Class*)ThrowingClass=0x0x20001ab8 (DoThrowIface*)this=0x0x20001abc (DoThrowIface*)ThrowingClass=0x0x20001abc Called doThrow. terminate called after throwing an instance of 'Exception' (gdb) where #0 0xd37bd440 in raise () from /usr/lib/libc.a(shr.o) #1 0xd384bca8 in abort () from /usr/lib/libc.a(shr.o) #2 0xd8055610 in __gnu_cxx::__verbose_terminate_handler () at _start_ :95 #3 0xd80609ec in __cxxabiv1::__terminate (handler=<incomplete type>) at _start_ :38 #4 0xd8055404 in std::terminate () at _start_ :48 #5 0xd8060d7c in __cxa_throw (obj=<incomplete type>, tinfo=<incomplete type>, dest=<incomplete type>) at _start_ :87 #6 0x10001604 in ThrowingClass::doThrow (this=0x20001ab8) at throwing_class.cc:24 #7 0x100006a8 in main (argc=1, argv=0x2ff22af4) at main.cc:39 g++ -v: Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/opt/freeware/libexec/gcc/powerpc-ibm-aix6.1.0.0/4.8.3/lto-wrapper Target: powerpc-ibm-aix6.1.0.0 Configured with: ../gcc-4.8.3/configure --with-as=/usr/bin/as --with-ld=/usr/bin/ld --enable-languages=c,c++,fortran --prefix=/opt/freeware --mandir=/opt/freeware/man --infodir=/opt/freeware/info --enable-version-specific-runtime-libs --disable-nls --enable-decimal-float=dpd --host=powerpc-ibm-aix6.1.0.0 Thread model: aix gcc version 4.8.3 (GCC) Sample sources: base.hh: #ifndef BASE_HH #define BASE_HH 1 class Exception { public: Exception() {} }; class Iface { public: virtual ~Iface() {} }; class Class { public: virtual ~Class() {} virtual Iface *getIface() = 0; }; class DoThrowIface : public Iface { public: virtual void doThrow() = 0; }; class Registrator { public: virtual Class* getClass() = 0; }; #endif /* BASE_HH */ throwing_class.hh: #ifndef THROWING_CLASS_HH #define THROWING_CLASS_HH 1 class ThrowingClass : public Class , public DoThrowIface { public: virtual void doThrow(); virtual Iface *getIface(); }; #endif /* THROWING_CLASS_HH */ throwing_class.cc: #include <iostream> #include "base.hh" #include "throwing_class.hh" extern Registrator *reg; // This class must be in separate object file class ThrowingClassRegistrator : public Registrator { public: ThrowingClassRegistrator() { reg = this; } virtual Class *getClass() { return new ThrowingClass(); } } ThrowingClassRegistrator_I; void ThrowingClass::doThrow() { std::cout << "Called doThrow." << std::endl; throw Exception(); } Iface *ThrowingClass::getIface() { std::cout << "(DoThrowIface*)this=0x" << (DoThrowIface*)this << std::endl; return static_cast<DoThrowIface*>(this); } main.cc: #include <iostream> #include <exception> #include "base.hh" #include "throwing_class.hh" Registrator *reg; int main(int argc, char *argv[]) { std::cout << "Case 1:" << std::endl; try { // This always works, but if I uncomment this, case 2 is also working. /* Class *throwingClass = new ThrowingClass(); std::cout << "(Class*)ThrowingClass=0x" << throwingClass << std::endl; DoThrowIface *throwIface = (DoThrowIface *)throwingClass->getIface(); std::cout << "(DoThrowIface*)ThrowingClass=0x" << throwIface << std::endl; throwIface->doThrow(); //*/ } catch (Exception const& e) { std::cout << "Thrown && catched BaseException." << std::endl; } catch (...) { std::cout << "General catch." << std::endl; } std::cout << std::endl << "Case 2:" << std::endl; try { Class *throwingClass = reg->getClass(); std::cout << "(Class*)ThrowingClass=0x" << throwingClass << std::endl; DoThrowIface *throwIface = (DoThrowIface *)throwingClass->getIface(); std::cout << "(DoThrowIface*)ThrowingClass=0x" << throwIface << std::endl; throwIface->doThrow(); } catch (Exception const& e) { std::cout << "Thrown && catched BaseException." << std::endl; } catch (...) { std::cout << "General catch." << std::endl; } std::cout << "End." << std::endl; return 0; }