]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix -freorder-blocks-and-partition glitch with Windows SEH
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 11 Feb 2021 23:16:49 +0000 (00:16 +0100)
committerEric Botcazou <ebotcazou@adacore.com>
Thu, 11 Feb 2021 23:21:29 +0000 (00:21 +0100)
Since GCC 8, the -freorder-blocks-and-partition pass can split a function
into hot and cold parts, thus generating 2 CIEs for a single function in
DWARF for exception purposes and doing an equivalent trick for Windows SEH.

Now the Windows system unwinder is picky when it comes to the boundary
between an active EH region and the end of the function and, therefore,
a nop may need to be added in specific cases.

gcc/
* config/i386/winnt.c (i386_pe_seh_unwind_emit): When switching to
the cold section, emit a nop before the directive if the previous
active instruction can throw.

gcc/config/i386/winnt.c

index 2ccd591bcbf1bf1c2b7736bbef13b75bf6f2196d..eae3ee2ef9a642d3994eedf08edb9fa382552085 100644 (file)
@@ -1231,6 +1231,10 @@ i386_pe_seh_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
   seh = cfun->machine->seh;
   if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
     {
+      /* See ix86_seh_fixup_eh_fallthru for the rationale.  */
+      rtx_insn *prev = prev_active_insn (insn);
+      if (prev && !insn_nothrow_p (prev))
+       fputs ("\tnop\n", asm_out_file);
       fputs ("\t.seh_endproc\n", asm_out_file);
       seh->in_cold_section = true;
       return;