From 618fa93ee154ec512957f06f114a2e4b8dfe8b31 Mon Sep 17 00:00:00 2001 From: rth Date: Wed, 14 Jan 2004 21:01:18 +0000 Subject: PR c++/12491 * except.c (struct eh_region): Add u.fixup.resolved. (resolve_one_fixup_region): Split out from ... (resolve_fixup_regions): ... here. * g++.dg/eh/cleanup2.C: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@75883 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/except.c | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) (limited to 'gcc/except.c') diff --git a/gcc/except.c b/gcc/except.c index 1468d3b909f..b735cc1aef3 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -189,6 +189,7 @@ struct eh_region GTY(()) struct eh_region_u_fixup { tree cleanup_exp; struct eh_region *real_region; + bool resolved; } GTY ((tag ("ERT_FIXUP"))) fixup; } GTY ((desc ("%0.type"))) u; @@ -889,30 +890,50 @@ collect_eh_region_array (void) } } +static void +resolve_one_fixup_region (struct eh_region *fixup) +{ + struct eh_region *cleanup, *real; + int j, n; + + n = cfun->eh->last_region_number; + cleanup = 0; + + for (j = 1; j <= n; ++j) + { + cleanup = cfun->eh->region_array[j]; + if (cleanup && cleanup->type == ERT_CLEANUP + && cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp) + break; + } + if (j > n) + abort (); + + real = cleanup->outer; + if (real && real->type == ERT_FIXUP) + { + if (!real->u.fixup.resolved) + resolve_one_fixup_region (real); + real = real->u.fixup.real_region; + } + + fixup->u.fixup.real_region = real; + fixup->u.fixup.resolved = true; +} + static void resolve_fixup_regions (void) { - int i, j, n = cfun->eh->last_region_number; + int i, n = cfun->eh->last_region_number; for (i = 1; i <= n; ++i) { struct eh_region *fixup = cfun->eh->region_array[i]; - struct eh_region *cleanup = 0; - if (! fixup || fixup->type != ERT_FIXUP) + if (!fixup || fixup->type != ERT_FIXUP || fixup->u.fixup.resolved) continue; - for (j = 1; j <= n; ++j) - { - cleanup = cfun->eh->region_array[j]; - if (cleanup && cleanup->type == ERT_CLEANUP - && cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp) - break; - } - if (j > n) - abort (); - - fixup->u.fixup.real_region = cleanup->outer; + resolve_one_fixup_region (fixup); } } -- cgit v1.2.1