Mercurial > hg > CbC > CbC_gcc
comparison gcc/except.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* Implements exception handling. | 1 /* Implements exception handling. |
2 Copyright (C) 1989-2018 Free Software Foundation, Inc. | 2 Copyright (C) 1989-2020 Free Software Foundation, Inc. |
3 Contributed by Mike Stump <mrs@cygnus.com>. | 3 Contributed by Mike Stump <mrs@cygnus.com>. |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
25 | 25 |
26 The representation of exceptions changes several times during | 26 The representation of exceptions changes several times during |
27 the compilation process: | 27 the compilation process: |
28 | 28 |
29 In the beginning, in the front end, we have the GENERIC trees | 29 In the beginning, in the front end, we have the GENERIC trees |
30 TRY_CATCH_EXPR, TRY_FINALLY_EXPR, WITH_CLEANUP_EXPR, | 30 TRY_CATCH_EXPR, TRY_FINALLY_EXPR, EH_ELSE_EXPR, WITH_CLEANUP_EXPR, |
31 CLEANUP_POINT_EXPR, CATCH_EXPR, and EH_FILTER_EXPR. | 31 CLEANUP_POINT_EXPR, CATCH_EXPR, and EH_FILTER_EXPR. |
32 | 32 |
33 During initial gimplification (gimplify.c) these are lowered | 33 During initial gimplification (gimplify.c) these are lowered to the |
34 to the GIMPLE_TRY, GIMPLE_CATCH, and GIMPLE_EH_FILTER nodes. | 34 GIMPLE_TRY, GIMPLE_CATCH, GIMPLE_EH_ELSE, and GIMPLE_EH_FILTER |
35 The WITH_CLEANUP_EXPR and CLEANUP_POINT_EXPR nodes are converted | 35 nodes. The WITH_CLEANUP_EXPR and CLEANUP_POINT_EXPR nodes are |
36 into GIMPLE_TRY_FINALLY nodes; the others are a more direct 1-1 | 36 converted into GIMPLE_TRY_FINALLY nodes; the others are a more |
37 conversion. | 37 direct 1-1 conversion. |
38 | 38 |
39 During pass_lower_eh (tree-eh.c) we record the nested structure | 39 During pass_lower_eh (tree-eh.c) we record the nested structure |
40 of the TRY nodes in EH_REGION nodes in CFUN->EH->REGION_TREE. | 40 of the TRY nodes in EH_REGION nodes in CFUN->EH->REGION_TREE. |
41 We expand the eh_protect_cleanup_actions langhook into MUST_NOT_THROW | 41 We expand the eh_protect_cleanup_actions langhook into MUST_NOT_THROW |
42 regions at this time. We can then flatten the statements within | 42 regions at this time. We can then flatten the statements within |
919 first instruction of some existing BB and return the newly | 919 first instruction of some existing BB and return the newly |
920 produced block. */ | 920 produced block. */ |
921 static basic_block | 921 static basic_block |
922 emit_to_new_bb_before (rtx_insn *seq, rtx_insn *insn) | 922 emit_to_new_bb_before (rtx_insn *seq, rtx_insn *insn) |
923 { | 923 { |
924 rtx_insn *last; | 924 rtx_insn *next, *last; |
925 basic_block bb; | 925 basic_block bb; |
926 edge e; | 926 edge e; |
927 edge_iterator ei; | 927 edge_iterator ei; |
928 | 928 |
929 /* If there happens to be a fallthru edge (possibly created by cleanup_cfg | 929 /* If there happens to be a fallthru edge (possibly created by cleanup_cfg |
932 for (ei = ei_start (BLOCK_FOR_INSN (insn)->preds); (e = ei_safe_edge (ei)); ) | 932 for (ei = ei_start (BLOCK_FOR_INSN (insn)->preds); (e = ei_safe_edge (ei)); ) |
933 if (e->flags & EDGE_FALLTHRU) | 933 if (e->flags & EDGE_FALLTHRU) |
934 force_nonfallthru (e); | 934 force_nonfallthru (e); |
935 else | 935 else |
936 ei_next (&ei); | 936 ei_next (&ei); |
937 last = emit_insn_before (seq, insn); | 937 |
938 /* Make sure to put the location of INSN or a subsequent instruction on SEQ | |
939 to avoid inheriting the location of the previous instruction. */ | |
940 next = insn; | |
941 while (next && !NONDEBUG_INSN_P (next)) | |
942 next = NEXT_INSN (next); | |
943 if (next) | |
944 last = emit_insn_before_setloc (seq, insn, INSN_LOCATION (next)); | |
945 else | |
946 last = emit_insn_before (seq, insn); | |
938 if (BARRIER_P (last)) | 947 if (BARRIER_P (last)) |
939 last = PREV_INSN (last); | 948 last = PREV_INSN (last); |
940 bb = create_basic_block (seq, last, BLOCK_FOR_INSN (insn)->prev_bb); | 949 bb = create_basic_block (seq, last, BLOCK_FOR_INSN (insn)->prev_bb); |
941 update_bb_for_insn (bb); | 950 update_bb_for_insn (bb); |
942 bb->flags |= BB_SUPERBLOCK; | 951 bb->flags |= BB_SUPERBLOCK; |
1004 bb = emit_to_new_bb_before (seq, label_rtx (lp->post_landing_pad)); | 1013 bb = emit_to_new_bb_before (seq, label_rtx (lp->post_landing_pad)); |
1005 bb->count = bb->next_bb->count; | 1014 bb->count = bb->next_bb->count; |
1006 make_single_succ_edge (bb, bb->next_bb, e_flags); | 1015 make_single_succ_edge (bb, bb->next_bb, e_flags); |
1007 if (current_loops) | 1016 if (current_loops) |
1008 { | 1017 { |
1009 struct loop *loop = bb->next_bb->loop_father; | 1018 class loop *loop = bb->next_bb->loop_father; |
1010 /* If we created a pre-header block, add the new block to the | 1019 /* If we created a pre-header block, add the new block to the |
1011 outer loop, otherwise to the loop itself. */ | 1020 outer loop, otherwise to the loop itself. */ |
1012 if (bb->next_bb == loop->header) | 1021 if (bb->next_bb == loop->header) |
1013 add_bb_to_loop (bb, loop_outer (loop)); | 1022 add_bb_to_loop (bb, loop_outer (loop)); |
1014 else | 1023 else |
1157 | 1166 |
1158 start_sequence (); | 1167 start_sequence (); |
1159 | 1168 |
1160 /* We're storing this libcall's address into memory instead of | 1169 /* We're storing this libcall's address into memory instead of |
1161 calling it directly. Thus, we must call assemble_external_libcall | 1170 calling it directly. Thus, we must call assemble_external_libcall |
1162 here, as we can not depend on emit_library_call to do it for us. */ | 1171 here, as we cannot depend on emit_library_call to do it for us. */ |
1163 assemble_external_libcall (personality); | 1172 assemble_external_libcall (personality); |
1164 mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs); | 1173 mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs); |
1165 emit_move_insn (mem, personality); | 1174 emit_move_insn (mem, personality); |
1166 | 1175 |
1167 mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs); | 1176 mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs); |
1378 rtx_insn *before = label_rtx (lp->post_landing_pad); | 1387 rtx_insn *before = label_rtx (lp->post_landing_pad); |
1379 bb = emit_to_new_bb_before (seq2, before); | 1388 bb = emit_to_new_bb_before (seq2, before); |
1380 make_single_succ_edge (bb, bb->next_bb, EDGE_FALLTHRU); | 1389 make_single_succ_edge (bb, bb->next_bb, EDGE_FALLTHRU); |
1381 if (current_loops) | 1390 if (current_loops) |
1382 { | 1391 { |
1383 struct loop *loop = bb->next_bb->loop_father; | 1392 class loop *loop = bb->next_bb->loop_father; |
1384 /* If we created a pre-header block, add the new block to the | 1393 /* If we created a pre-header block, add the new block to the |
1385 outer loop, otherwise to the loop itself. */ | 1394 outer loop, otherwise to the loop itself. */ |
1386 if (bb->next_bb == loop->header) | 1395 if (bb->next_bb == loop->header) |
1387 add_bb_to_loop (bb, loop_outer (loop)); | 1396 add_bb_to_loop (bb, loop_outer (loop)); |
1388 else | 1397 else |
1416 if (num_dispatch == 1) | 1425 if (num_dispatch == 1) |
1417 { | 1426 { |
1418 make_single_succ_edge (bb, bb->next_bb, EDGE_FALLTHRU); | 1427 make_single_succ_edge (bb, bb->next_bb, EDGE_FALLTHRU); |
1419 if (current_loops) | 1428 if (current_loops) |
1420 { | 1429 { |
1421 struct loop *loop = bb->next_bb->loop_father; | 1430 class loop *loop = bb->next_bb->loop_father; |
1422 /* If we created a pre-header block, add the new block to the | 1431 /* If we created a pre-header block, add the new block to the |
1423 outer loop, otherwise to the loop itself. */ | 1432 outer loop, otherwise to the loop itself. */ |
1424 if (bb->next_bb == loop->header) | 1433 if (bb->next_bb == loop->header) |
1425 add_bb_to_loop (bb, loop_outer (loop)); | 1434 add_bb_to_loop (bb, loop_outer (loop)); |
1426 else | 1435 else |
1754 { | 1763 { |
1755 note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX); | 1764 note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX); |
1756 if (note == NULL) | 1765 if (note == NULL) |
1757 return; | 1766 return; |
1758 } | 1767 } |
1768 else if (is_a <rtx_insn *> (note_or_insn)) | |
1769 return; | |
1759 note = XEXP (note, 0); | 1770 note = XEXP (note, 0); |
1760 | 1771 |
1761 for (insn = first; insn != last ; insn = NEXT_INSN (insn)) | 1772 for (insn = first; insn != last ; insn = NEXT_INSN (insn)) |
1762 if (!find_reg_note (insn, REG_EH_REGION, NULL_RTX) | 1773 if (!find_reg_note (insn, REG_EH_REGION, NULL_RTX) |
1763 && insn_could_throw_p (insn)) | 1774 && insn_could_throw_p (insn)) |
1776 { | 1787 { |
1777 note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX); | 1788 note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX); |
1778 if (note == NULL) | 1789 if (note == NULL) |
1779 return; | 1790 return; |
1780 } | 1791 } |
1792 else if (is_a <rtx_insn *> (note_or_insn)) | |
1793 return; | |
1781 note = XEXP (note, 0); | 1794 note = XEXP (note, 0); |
1782 | 1795 |
1783 for (insn = last; insn != first; insn = PREV_INSN (insn)) | 1796 for (insn = last; insn != first; insn = PREV_INSN (insn)) |
1784 if (insn_could_throw_p (insn)) | 1797 if (insn_could_throw_p (insn)) |
1785 add_reg_note (insn, REG_EH_REGION, note); | 1798 add_reg_note (insn, REG_EH_REGION, note); |
2282 else | 2295 else |
2283 { | 2296 { |
2284 if (rtx handler = EH_RETURN_HANDLER_RTX) | 2297 if (rtx handler = EH_RETURN_HANDLER_RTX) |
2285 emit_move_insn (handler, crtl->eh.ehr_handler); | 2298 emit_move_insn (handler, crtl->eh.ehr_handler); |
2286 else | 2299 else |
2287 error ("__builtin_eh_return not supported on this target"); | 2300 error ("%<__builtin_eh_return%> not supported on this target"); |
2288 } | 2301 } |
2289 | 2302 |
2290 emit_label (around_label); | 2303 emit_label (around_label); |
2291 } | 2304 } |
2292 | 2305 |
3406 { | 3419 { |
3407 if (r->index == i) | 3420 if (r->index == i) |
3408 count_r++; | 3421 count_r++; |
3409 else | 3422 else |
3410 { | 3423 { |
3411 error ("region_array is corrupted for region %i", r->index); | 3424 error ("%<region_array%> is corrupted for region %i", r->index); |
3412 err = true; | 3425 err = true; |
3413 } | 3426 } |
3414 } | 3427 } |
3415 | 3428 |
3416 count_lp = 0; | 3429 count_lp = 0; |
3419 { | 3432 { |
3420 if (lp->index == i) | 3433 if (lp->index == i) |
3421 count_lp++; | 3434 count_lp++; |
3422 else | 3435 else |
3423 { | 3436 { |
3424 error ("lp_array is corrupted for lp %i", lp->index); | 3437 error ("%<lp_array%> is corrupted for lp %i", lp->index); |
3425 err = true; | 3438 err = true; |
3426 } | 3439 } |
3427 } | 3440 } |
3428 | 3441 |
3429 depth = nvisited_lp = nvisited_r = 0; | 3442 depth = nvisited_lp = nvisited_r = 0; |
3431 r = fun->eh->region_tree; | 3444 r = fun->eh->region_tree; |
3432 while (1) | 3445 while (1) |
3433 { | 3446 { |
3434 if ((*fun->eh->region_array)[r->index] != r) | 3447 if ((*fun->eh->region_array)[r->index] != r) |
3435 { | 3448 { |
3436 error ("region_array is corrupted for region %i", r->index); | 3449 error ("%<region_array%> is corrupted for region %i", r->index); |
3437 err = true; | 3450 err = true; |
3438 } | 3451 } |
3439 if (r->outer != outer) | 3452 if (r->outer != outer) |
3440 { | 3453 { |
3441 error ("outer block of region %i is wrong", r->index); | 3454 error ("outer block of region %i is wrong", r->index); |
3450 | 3463 |
3451 for (lp = r->landing_pads; lp ; lp = lp->next_lp) | 3464 for (lp = r->landing_pads; lp ; lp = lp->next_lp) |
3452 { | 3465 { |
3453 if ((*fun->eh->lp_array)[lp->index] != lp) | 3466 if ((*fun->eh->lp_array)[lp->index] != lp) |
3454 { | 3467 { |
3455 error ("lp_array is corrupted for lp %i", lp->index); | 3468 error ("%<lp_array%> is corrupted for lp %i", lp->index); |
3456 err = true; | 3469 err = true; |
3457 } | 3470 } |
3458 if (lp->region != r) | 3471 if (lp->region != r) |
3459 { | 3472 { |
3460 error ("region of lp %i is wrong", lp->index); | 3473 error ("region of lp %i is wrong", lp->index); |
3487 error ("tree list ends on depth %i", depth); | 3500 error ("tree list ends on depth %i", depth); |
3488 err = true; | 3501 err = true; |
3489 } | 3502 } |
3490 if (count_r != nvisited_r) | 3503 if (count_r != nvisited_r) |
3491 { | 3504 { |
3492 error ("region_array does not match region_tree"); | 3505 error ("%<region_array%> does not match %<region_tree%>"); |
3493 err = true; | 3506 err = true; |
3494 } | 3507 } |
3495 if (count_lp != nvisited_lp) | 3508 if (count_lp != nvisited_lp) |
3496 { | 3509 { |
3497 error ("lp_array does not match region_tree"); | 3510 error ("%<lp_array%> does not match %<region_tree%>"); |
3498 err = true; | 3511 err = true; |
3499 } | 3512 } |
3500 | 3513 |
3501 if (err) | 3514 if (err) |
3502 { | 3515 { |
3503 dump_eh_tree (stderr, fun); | 3516 dump_eh_tree (stderr, fun); |
3504 internal_error ("verify_eh_tree failed"); | 3517 internal_error ("%qs failed", __func__); |
3505 } | 3518 } |
3506 } | 3519 } |
3507 | 3520 |
3508 #include "gt-except.h" | 3521 #include "gt-except.h" |