(root)/
gcc-13.2.0/
gcc/
except.h
       1  /* Exception Handling interface routines.
       2     Copyright (C) 1996-2023 Free Software Foundation, Inc.
       3     Contributed by Mike Stump <mrs@cygnus.com>.
       4  
       5  This file is part of GCC.
       6  
       7  GCC is free software; you can redistribute it and/or modify it under
       8  the terms of the GNU General Public License as published by the Free
       9  Software Foundation; either version 3, or (at your option) any later
      10  version.
      11  
      12  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13  WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15  for more details.
      16  
      17  You should have received a copy of the GNU General Public License
      18  along with GCC; see the file COPYING3.  If not see
      19  <http://www.gnu.org/licenses/>.  */
      20  
      21  /* No include guards here, but define an include file marker anyway, so
      22     that the compiler can keep track of where this file is included.  This
      23     is e.g. used to avoid including this file in front-end specific files.  */
      24  #ifndef GCC_EXCEPT_H
      25  #define GCC_EXCEPT_H
      26  
      27  
      28  struct function;
      29  struct eh_region_d;
      30  
      31  /* The type of an exception region.  */
      32  enum eh_region_type
      33  {
      34    /* CLEANUP regions implement e.g. destructors run when exiting a block.
      35       They can be generated from both GIMPLE_TRY_FINALLY and GIMPLE_TRY_CATCH
      36       nodes.  It is expected by the runtime that cleanup regions will *not*
      37       resume normal program flow, but will continue propagation of the
      38       exception.  */
      39    ERT_CLEANUP,
      40  
      41    /* TRY regions implement catching an exception.  The list of types associated
      42       with the attached catch handlers is examined in order by the runtime and
      43       control is transferred to the appropriate handler.  Note that a NULL type
      44       list is a catch-all handler, and that it will catch *all* exceptions
      45       including those originating from a different language.  */
      46    ERT_TRY,
      47  
      48    /* ALLOWED_EXCEPTIONS regions implement exception filtering, e.g. the
      49       throw(type-list) specification that can be added to C++ functions.
      50       The runtime examines the thrown exception vs the type list, and if
      51       the exception does not match, transfers control to the handler.  The
      52       normal handler for C++ calls __cxa_call_unexpected.  */
      53    ERT_ALLOWED_EXCEPTIONS,
      54  
      55    /* MUST_NOT_THROW regions prevent all exceptions from propagating.  This
      56       region type is used in C++ to surround destructors being run inside a
      57       CLEANUP region.  This differs from an ALLOWED_EXCEPTIONS region with
      58       an empty type list in that the runtime is prepared to terminate the
      59       program directly.  We only generate code for MUST_NOT_THROW regions
      60       along control paths that are already handling an exception within the
      61       current function.  */
      62    ERT_MUST_NOT_THROW
      63  };
      64  
      65  
      66  /* A landing pad for a given exception region.  Any transfer of control
      67     from the EH runtime to the function happens at a landing pad.  */
      68  
      69  struct GTY(()) eh_landing_pad_d
      70  {
      71    /* The linked list of all landing pads associated with the region.  */
      72    struct eh_landing_pad_d *next_lp;
      73  
      74    /* The region with which this landing pad is associated.  */
      75    struct eh_region_d *region;
      76  
      77    /* At the gimple level, the location to which control will be transferred
      78       for this landing pad.  There can be both EH and normal edges into the
      79       block containing the post-landing-pad label.  */
      80    tree post_landing_pad;
      81  
      82    /* At the rtl level, the location to which the runtime will transfer
      83       control.  This differs from the post-landing-pad in that the target's
      84       EXCEPTION_RECEIVER pattern will be expanded here, as well as other
      85       bookkeeping specific to exceptions.  There must not be normal edges
      86       into the block containing the landing-pad label.  */
      87    rtx_code_label *landing_pad;
      88  
      89    /* The index of this landing pad within fun->eh->lp_array.  */
      90    int index;
      91  };
      92  
      93  /* A catch handler associated with an ERT_TRY region.  */
      94  
      95  struct GTY(()) eh_catch_d
      96  {
      97    /* The double-linked list of all catch handlers for the region.  */
      98    struct eh_catch_d *next_catch;
      99    struct eh_catch_d *prev_catch;
     100  
     101    /* A TREE_LIST of runtime type objects that this catch handler
     102       will catch, or NULL if all exceptions are caught.  */
     103    tree type_list;
     104  
     105    /* A TREE_LIST of INTEGER_CSTs that correspond to the type_list entries,
     106       having been mapped by assign_filter_values.  These integers are to be
     107       compared against the __builtin_eh_filter value.  */
     108    tree filter_list;
     109  
     110    /* The code that should be executed if this catch handler matches the
     111       thrown exception.  This label is only maintained until
     112       pass_lower_eh_dispatch, at which point it is cleared.  */
     113    tree label;
     114  };
     115  
     116  /* Describes one exception region.  */
     117  
     118  struct GTY(()) eh_region_d
     119  {
     120    /* The immediately surrounding region.  */
     121    struct eh_region_d *outer;
     122  
     123    /* The list of immediately contained regions.  */
     124    struct eh_region_d *inner;
     125    struct eh_region_d *next_peer;
     126  
     127    /* The index of this region within fun->eh->region_array.  */
     128    int index;
     129  
     130    /* Each region does exactly one thing.  */
     131    enum eh_region_type type;
     132  
     133    /* Holds the action to perform based on the preceding type.  */
     134    union eh_region_u {
     135      struct eh_region_u_try {
     136        /* The double-linked list of all catch handlers for this region.  */
     137        struct eh_catch_d *first_catch;
     138        struct eh_catch_d *last_catch;
     139      } GTY ((tag ("ERT_TRY"))) eh_try;
     140  
     141      struct eh_region_u_allowed {
     142        /* A TREE_LIST of runtime type objects allowed to pass.  */
     143        tree type_list;
     144        /* The code that should be executed if the thrown exception does
     145  	 not match the type list.  This label is only maintained until
     146  	 pass_lower_eh_dispatch, at which point it is cleared.  */
     147        tree label;
     148        /* The integer that will be passed by the runtime to signal that
     149  	 we should execute the code at LABEL.  This integer is assigned
     150  	 by assign_filter_values and is to be compared against the
     151  	 __builtin_eh_filter value.  */
     152        int filter;
     153      } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
     154  
     155      struct eh_region_u_must_not_throw {
     156        /* A function decl to be invoked if this region is actually reachable
     157  	 from within the function, rather than implementable from the runtime.
     158  	 The normal way for this to happen is for there to be a CLEANUP region
     159  	 contained within this MUST_NOT_THROW region.  Note that if the
     160  	 runtime handles the MUST_NOT_THROW region, we have no control over
     161  	 what termination function is called; it will be decided by the
     162  	 personality function in effect for this CIE.  */
     163        tree failure_decl;
     164        /* The location assigned to the call of FAILURE_DECL, if expanded.  */
     165        location_t failure_loc;
     166      } GTY ((tag ("ERT_MUST_NOT_THROW"))) must_not_throw;
     167    } GTY ((desc ("%0.type"))) u;
     168  
     169    /* The list of landing pads associated with this region.  */
     170    struct eh_landing_pad_d *landing_pads;
     171  
     172    /* EXC_PTR and FILTER values copied from the runtime for this region.
     173       Each region gets its own psuedos so that if there are nested exceptions
     174       we do not overwrite the values of the first exception.  */
     175    rtx exc_ptr_reg, filter_reg;
     176  
     177    /* True if this region should use __cxa_end_cleanup instead
     178       of _Unwind_Resume.  */
     179    bool use_cxa_end_cleanup;
     180  };
     181  
     182  typedef struct eh_landing_pad_d *eh_landing_pad;
     183  typedef struct eh_catch_d *eh_catch;
     184  typedef struct eh_region_d *eh_region;
     185  
     186  
     187  
     188  
     189  /* The exception status for each function.  */
     190  
     191  struct GTY(()) eh_status
     192  {
     193    /* The tree of all regions for this function.  */
     194    eh_region region_tree;
     195  
     196    /* The same information as an indexable array.  */
     197    vec<eh_region, va_gc> *region_array;
     198  
     199    /* The landing pads as an indexable array.  */
     200    vec<eh_landing_pad, va_gc> *lp_array;
     201  
     202    /* At the gimple level, a mapping from gimple statement to landing pad
     203       or must-not-throw region.  See record_stmt_eh_region.  */
     204    hash_map<gimple *, int> *GTY(()) throw_stmt_table;
     205  
     206    /* All of the runtime type data used by the function.  These objects
     207       are emitted to the lang-specific-data-area for the function.  */
     208    vec<tree, va_gc> *ttype_data;
     209  
     210    /* The table of all action chains.  These encode the eh_region tree in
     211       a compact form for use by the runtime, and is also emitted to the
     212       lang-specific-data-area.  Note that the ARM EABI uses a different
     213       format for the encoding than all other ports.  */
     214    union eh_status_u {
     215      vec<tree, va_gc> *GTY((tag ("1"))) arm_eabi;
     216      vec<uchar, va_gc> *GTY((tag ("0"))) other;
     217    } GTY ((desc ("targetm.arm_eabi_unwinder"))) ehspec_data;
     218  };
     219  
     220  
     221  /* Invokes CALLBACK for every exception handler label.  Only used by old
     222     loop hackery; should not be used by new code.  */
     223  extern void for_each_eh_label (void (*) (rtx));
     224  
     225  extern void init_eh_for_function (void);
     226  
     227  extern void remove_eh_landing_pad (eh_landing_pad);
     228  extern void remove_eh_handler (eh_region);
     229  extern void remove_unreachable_eh_regions (sbitmap);
     230  
     231  extern bool current_function_has_exception_handlers (void);
     232  extern void output_function_exception_table (int);
     233  
     234  extern rtx expand_builtin_eh_pointer (tree);
     235  extern rtx expand_builtin_eh_filter (tree);
     236  extern rtx expand_builtin_eh_copy_values (tree);
     237  extern void expand_builtin_unwind_init (void);
     238  extern rtx expand_builtin_eh_return_data_regno (tree);
     239  extern rtx expand_builtin_extract_return_addr (tree);
     240  extern void expand_builtin_init_dwarf_reg_sizes (tree);
     241  extern rtx expand_builtin_frob_return_addr (tree);
     242  extern rtx expand_builtin_dwarf_sp_column (void);
     243  extern void expand_builtin_eh_return (tree, tree);
     244  extern void expand_eh_return (void);
     245  extern rtx expand_builtin_extend_pointer (tree);
     246  
     247  typedef tree (*duplicate_eh_regions_map) (tree, void *);
     248  extern hash_map<void *, void *> *duplicate_eh_regions
     249    (struct function *, eh_region, int, duplicate_eh_regions_map, void *);
     250  
     251  extern void sjlj_emit_function_exit_after (rtx_insn *);
     252  extern void update_sjlj_context (void);
     253  
     254  extern eh_region gen_eh_region_cleanup (eh_region);
     255  extern eh_region gen_eh_region_try (eh_region);
     256  extern eh_region gen_eh_region_allowed (eh_region, tree);
     257  extern eh_region gen_eh_region_must_not_throw (eh_region);
     258  
     259  extern eh_catch gen_eh_region_catch (eh_region, tree);
     260  extern eh_landing_pad gen_eh_landing_pad (eh_region);
     261  
     262  extern eh_region get_eh_region_from_number_fn (struct function *, int);
     263  extern eh_region get_eh_region_from_number (int);
     264  extern eh_landing_pad get_eh_landing_pad_from_number_fn (struct function*,int);
     265  extern eh_landing_pad get_eh_landing_pad_from_number (int);
     266  extern eh_region get_eh_region_from_lp_number_fn (struct function *, int);
     267  extern eh_region get_eh_region_from_lp_number (int);
     268  
     269  extern eh_region eh_region_outermost (struct function *, eh_region, eh_region);
     270  
     271  extern void make_reg_eh_region_note (rtx_insn *insn, int ecf_flags, int lp_nr);
     272  extern void make_reg_eh_region_note_nothrow_nononlocal (rtx_insn *);
     273  
     274  extern void verify_eh_tree (struct function *);
     275  extern void dump_eh_tree (FILE *, struct function *);
     276  void debug_eh_tree (struct function *);
     277  extern void add_type_for_runtime (tree);
     278  extern tree lookup_type_for_runtime (tree);
     279  extern void assign_filter_values (void);
     280  
     281  extern eh_region get_eh_region_from_rtx (const_rtx);
     282  extern eh_landing_pad get_eh_landing_pad_from_rtx (const_rtx);
     283  
     284  extern void finish_eh_generation (void);
     285  
     286  struct GTY(()) throw_stmt_node {
     287    gimple *stmt;
     288    int lp_nr;
     289  };
     290  
     291  extern hash_map<gimple *, int> *get_eh_throw_stmt_table (struct function *);
     292  extern void set_eh_throw_stmt_table (function *, hash_map<gimple *, int> *);
     293  
     294  enum eh_personality_kind {
     295    eh_personality_none,
     296    eh_personality_any,
     297    eh_personality_lang
     298  };
     299  
     300  extern enum eh_personality_kind
     301  function_needs_eh_personality (struct function *);
     302  
     303  /* Pre-order iteration within the eh_region tree.  */
     304  
     305  inline eh_region
     306  ehr_next (eh_region r, eh_region start)
     307  {
     308    if (r->inner)
     309      r = r->inner;
     310    else if (r->next_peer && r != start)
     311      r = r->next_peer;
     312    else
     313      {
     314        do
     315  	{
     316  	  r = r->outer;
     317  	  if (r == start)
     318  	    return NULL;
     319  	}
     320        while (r->next_peer == NULL);
     321        r = r->next_peer;
     322      }
     323    return r;
     324  }
     325  
     326  #define FOR_ALL_EH_REGION_AT(R, START) \
     327    for ((R) = (START); (R) != NULL; (R) = ehr_next (R, START))
     328  
     329  #define FOR_ALL_EH_REGION_FN(R, FN) \
     330    for ((R) = (FN)->eh->region_tree; (R) != NULL; (R) = ehr_next (R, NULL))
     331  
     332  #define FOR_ALL_EH_REGION(R) FOR_ALL_EH_REGION_FN (R, cfun)
     333  
     334  #endif