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"