diff options
author | Mark Mitchell <mark@codesourcery.com> | 2003-03-17 06:09:30 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2003-03-17 06:09:30 +0000 |
commit | bafb714bac23b833d326cfdeb6ef3d58965640a5 (patch) | |
tree | e517b3e747497dcfd5c40ea4efb3157765c7da39 /gcc/except.c | |
parent | 30492adf69319654cb870eb4634dc53164d3cbc0 (diff) | |
download | gcc-bafb714bac23b833d326cfdeb6ef3d58965640a5.zip gcc-bafb714bac23b833d326cfdeb6ef3d58965640a5.tar.gz gcc-bafb714bac23b833d326cfdeb6ef3d58965640a5.tar.bz2 |
re PR c++/8805 (compile time regression with many member variables)
PR c++/8805
* except.c (eh_region_u_cleanup): Add prev_try.
(expand_eh_region_end_cleanup): Set it.
(reachable_handlers): Use it to skip over cleanup blocks.
PR c++/8805
* g++.dg/eh/cleanup1.C: New test.
From-SVN: r64465
Diffstat (limited to 'gcc/except.c')
-rw-r--r-- | gcc/except.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/gcc/except.c b/gcc/except.c index 16613c4..3c80f60 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -186,6 +186,7 @@ struct eh_region GTY(()) we can match up fixup regions. */ struct eh_region_u_cleanup { tree exp; + struct eh_region *prev_try; } GTY ((tag ("ERT_CLEANUP"))) cleanup; /* The real region (by expression and by pointer) that fixup code @@ -553,6 +554,7 @@ expand_eh_region_end_cleanup (handler) region->type = ERT_CLEANUP; region->label = gen_label_rtx (); region->u.cleanup.exp = handler; + region->u.cleanup.prev_try = cfun->eh->try_region; around_label = gen_label_rtx (); emit_jump (around_label); @@ -2762,10 +2764,20 @@ reachable_handlers (insn) region = region->outer; } - for (; region; region = region->outer) - if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT) - break; - + while (region) + { + if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT) + break; + /* If we have processed one cleanup, there is no point in + processing any more of them. Each cleanup will have an edge + to the next outer cleanup region, so the flow graph will be + accurate. */ + if (region->type == ERT_CLEANUP) + region = region->u.cleanup.prev_try; + else + region = region->outer; + } + return info.handlers; } |