]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/dwarf2cfi.c
c++: Handle multiple aggregate overloads [PR95319].
[thirdparty/gcc.git] / gcc / dwarf2cfi.c
index 4cfb91b8d40810ffb1331a1e084a917e0ed7f9c2..0d179b388e49256e31af13cf6a9fedd87cd53728 100644 (file)
@@ -1,5 +1,5 @@
 /* Dwarf2 Call Frame Information helper routines.
-   Copyright (C) 1992-2018 Free Software Foundation, Inc.
+   Copyright (C) 1992-2020 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -68,6 +68,12 @@ struct GTY(()) dw_cfi_row
 
   /* The expressions for any register column that is saved.  */
   cfi_vec reg_save;
+
+  /* True if the register window is saved.  */
+  bool window_save;
+
+  /* True if the return address is in a mangled state.  */
+  bool ra_mangled;
 };
 
 /* The caller's ORIG_REG is saved in SAVED_IN_REG.  */
@@ -147,6 +153,9 @@ struct dw_trace_info
 
   /* True if we've seen different values incoming to beg_true_args_size.  */
   bool args_size_undefined;
+
+  /* True if we've seen an insn with a REG_ARGS_SIZE note before EH_HEAD.  */
+  bool args_size_defined_for_eh;
 };
 
 
@@ -763,6 +772,12 @@ cfi_row_equal_p (dw_cfi_row *a, dw_cfi_row *b)
         return false;
     }
 
+  if (a->window_save != b->window_save)
+    return false;
+
+  if (a->ra_mangled != b->ra_mangled)
+    return false;
+
   return true;
 }
 
@@ -942,6 +957,9 @@ notice_args_size (rtx_insn *insn)
   if (note == NULL)
     return;
 
+  if (!cur_trace->eh_head)
+    cur_trace->args_size_defined_for_eh = true;
+
   args_size = get_args_size (note);
   delta = args_size - cur_trace->end_true_args_size;
   if (known_eq (delta, 0))
@@ -1358,8 +1376,9 @@ dwarf2out_frame_debug_cfa_restore (rtx reg)
 }
 
 /* A subroutine of dwarf2out_frame_debug, process a REG_CFA_WINDOW_SAVE.
-   ??? Perhaps we should note in the CIE where windows are saved (instead of
-   assuming 0(cfa)) and what registers are in the window.  */
+
+   ??? Perhaps we should note in the CIE where windows are saved (instead
+   of assuming 0(cfa)) and what registers are in the window.  */
 
 static void
 dwarf2out_frame_debug_cfa_window_save (void)
@@ -1368,6 +1387,22 @@ dwarf2out_frame_debug_cfa_window_save (void)
 
   cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
   add_cfi (cfi);
+  cur_row->window_save = true;
+}
+
+/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_TOGGLE_RA_MANGLE.
+   Note: DW_CFA_GNU_window_save dwarf opcode is reused for toggling RA mangle
+   state, this is a target specific operation on AArch64 and can only be used
+   on other targets if they don't use the window save operation otherwise.  */
+
+static void
+dwarf2out_frame_debug_cfa_toggle_ra_mangle (void)
+{
+  dw_cfi_ref cfi = new_cfi ();
+
+  cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
+  add_cfi (cfi);
+  cur_row->ra_mangled = !cur_row->ra_mangled;
 }
 
 /* Record call frame debugging information for an expression EXPR,
@@ -1762,7 +1797,7 @@ dwarf2out_frame_debug_expr (rtx expr)
 
          /* Rule 6 */
        case CONST_INT:
-       case POLY_INT_CST:
+       case CONST_POLY_INT:
          cur_trace->cfa_temp.reg = dwf_regno (dest);
          cur_trace->cfa_temp.offset = rtx_to_poly_int64 (src);
          break;
@@ -2127,8 +2162,11 @@ dwarf2out_frame_debug (rtx_insn *insn)
        break;
 
       case REG_CFA_TOGGLE_RA_MANGLE:
+       dwarf2out_frame_debug_cfa_toggle_ra_mangle ();
+       handled_one = true;
+       break;
+
       case REG_CFA_WINDOW_SAVE:
-       /* We overload both of these operations onto the same DWARF opcode.  */
        dwarf2out_frame_debug_cfa_window_save ();
        handled_one = true;
        break;
@@ -2193,6 +2231,25 @@ change_cfi_row (dw_cfi_row *old_row, dw_cfi_row *new_row)
       else if (!cfi_equal_p (r_old, r_new))
         add_cfi (r_new);
     }
+
+  if (!old_row->window_save && new_row->window_save)
+    {
+      dw_cfi_ref cfi = new_cfi ();
+
+      gcc_assert (!old_row->ra_mangled && !new_row->ra_mangled);
+      cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
+      add_cfi (cfi);
+    }
+
+  if (old_row->ra_mangled != new_row->ra_mangled)
+    {
+      dw_cfi_ref cfi = new_cfi ();
+
+      gcc_assert (!old_row->window_save && !new_row->window_save);
+      /* DW_CFA_GNU_window_save is reused for toggling RA mangle state.  */
+      cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
+      add_cfi (cfi);
+    }
 }
 
 /* Examine CFI and return true if a cfi label and set_loc is needed
@@ -2417,6 +2474,13 @@ create_trace_edges (rtx_insn *insn)
              rtx_insn *lab = as_a <rtx_insn *> (XEXP (RTVEC_ELT (vec, i), 0));
              maybe_record_trace_start (lab, insn);
            }
+
+         /* Handle casesi dispatch insns.  */
+         if ((tmp = tablejump_casesi_pattern (insn)) != NULL_RTX)
+           {
+             rtx_insn * lab = label_ref_label (XEXP (SET_SRC (tmp), 2));
+             maybe_record_trace_start (lab, insn);
+           }
        }
       else if (computed_jump_p (insn))
        {
@@ -2820,11 +2884,17 @@ connect_traces (void)
 
          if (ti->switch_sections)
            prev_args_size = 0;
+
          if (ti->eh_head == NULL)
            continue;
-         gcc_assert (!ti->args_size_undefined);
 
-         if (maybe_ne (ti->beg_delay_args_size, prev_args_size))
+         /* We require either the incoming args_size values to match or the
+            presence of an insn setting it before the first EH insn.  */
+         gcc_assert (!ti->args_size_undefined || ti->args_size_defined_for_eh);
+
+         /* In the latter case, we force the creation of a CFI note.  */
+         if (ti->args_size_undefined
+             || maybe_ne (ti->beg_delay_args_size, prev_args_size))
            {
              /* ??? Search back to previous CFI note.  */
              add_cfi_insn = PREV_INSN (ti->eh_head);