struct A {}; struct B { virtual ~B(); }; B::~B () {} struct C { void foo (short &, B &); }; struct D { void *d1; C *d2; virtual void virt (void) {} }; struct E { D *e1; B *e2; }; struct F { void bar (void *, B &); }; F *p __attribute__((weak)); volatile int r; void C::foo (short &x, B &) { if (r) throw A (); x = 1; } void F::bar (void *, B &) { throw A (); } void baz (E &x) { short g = 0; B b = *x.e2; x.e1->d2->foo (g, b); if (g) p->bar(x.e1->d1, b); } int main () { F g; D s; E h; p = &g; h.e1 = &s; try { baz (h); } catch (A &) { } return 0; } fails on ia64 at least with gcc trunk and 4.1.1 at -O2. The problem is a br.call not at the end of a bundle where the EH region ends right after it: .mbb ld8 r39 = [r15] br.call.sptk.many b0 = _ZN1F3barEPvR1B# [.LEHE0:] nop 0 ;; As br.call sets rp to the address of the next bundle, when the personality routine is called it doesn't think this call is inside of the .LEHB0 .. .LEHE0 EH region and calls std::terminate.
Subject: Bug 30230 Author: jakub Date: Thu Dec 21 12:59:06 2006 New Revision: 120103 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=120103 Log: PR target/30230 * config/ia64/ia64.c (ia64_add_bundle_selector_before): New function. (bundling): Use it. * g++.dg/eh/ia64-2.C: New test. Added: trunk/gcc/testsuite/g++.dg/eh/ia64-2.C Modified: trunk/gcc/ChangeLog trunk/gcc/config/ia64/ia64.c trunk/gcc/testsuite/ChangeLog
Subject: Bug 30230 Author: jakub Date: Thu Dec 21 13:04:08 2006 New Revision: 120104 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=120104 Log: PR target/30230 * config/ia64/ia64.c (ia64_add_bundle_selector_before): New function. (bundling): Use it. * g++.dg/eh/ia64-2.C: New test. Added: branches/gcc-4_2-branch/gcc/testsuite/g++.dg/eh/ia64-2.C Modified: branches/gcc-4_2-branch/gcc/ChangeLog branches/gcc-4_2-branch/gcc/config/ia64/ia64.c branches/gcc-4_2-branch/gcc/testsuite/ChangeLog
Subject: Bug 30230 Author: jakub Date: Thu Dec 21 13:06:37 2006 New Revision: 120105 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=120105 Log: PR target/30230 * config/ia64/ia64.c (ia64_add_bundle_selector_before): New function. (bundling): Use it. * g++.dg/eh/ia64-2.C: New test. Added: branches/gcc-4_1-branch/gcc/testsuite/g++.dg/eh/ia64-2.C Modified: branches/gcc-4_1-branch/gcc/ChangeLog branches/gcc-4_1-branch/gcc/config/ia64/ia64.c branches/gcc-4_1-branch/gcc/testsuite/ChangeLog
Fixed by Jakub's patch for 4.1, 4.2, and mainline.