Hello, The attached patch is a proposal to plug a hole in create_trace_edges (dwarf2cfi.c), which doesn't handle casesi dispatch insns.
The visible misbehavior we observed is a failure in a cross configuration of a recent acats test for Ada, a very simplified sketch of which is provided below. This was with gcc-7 on a port which has been deprecated since then, but ISTM the problem remains latent for other ports. Essentially, we had a jump insn like: if X <= 4 -- for case values set pc *(&label_59 + kind * 4) -- 0 .. 4 else set pc &label_151 for the case statement, and the tablejump_p processing code in create_trace_edges only gets through the first 5 possible targets. The missing edge in the re-created control-flow graph eventually materialized as missing .cfi_remember_state/.cfi_restore_state pairs in the output, which resulted in bogus exception handling behavior. The insn pattern corresponds to the one handled in patch_jump_insn (cfgrtl.c). The proposed patch extracts the pattern recognition code in a separate function and uses it in both patch_jump_insn and create_trace_edges. This fixed our problem on the cross port (arm-vxworks6) and we have been running with it for all our gcc-7 and gcc-8 ports since then, about 6 months ago now. It also bootstraps and regression tests fine with mainline on x86_64-linux. Ok, to commit ? Thanks in advance! With Kind Regards, Olivier 2019-08-09 Olivier Hainque <hain...@adacore.com> * rtl.h (tablejump_casesi_pattern): New helper, casesi recognition logic originating from code in cfgrtl.c. * cfgrtl.c (patch_jump_insn): Use it. * dwarf2cfi.c (create_trace_edges): Handle casesi patterns. -- with Ada.Assertions; package body Casesi is function Process (X : Natural) return String is begin case X is when 0 => raise Ada.Assertions.Assertion_Error; when 1 => raise Ada.Assertions.Assertion_Error; when 2 => return (1 .. 4 => 'T'); when 3 => return (2 .. 8 => 'T'); when 4 => return "hello"; when others => return (1 .. 0 => <>); end case; end; procedure Try (X : Natural) is begin declare Code : String := Process (X); begin if X < 2 then raise Program_Error; end if; end; exception when Ada.Assertions.Assertion_Error => null; end; end; package Casesi is procedure Try (X : Natural); end; with Casesi; procedure Test_Casesi is begin Casesi.Try (1); Casesi.Try (2); Casesi.Try (3); end;
casesi.diff
Description: Binary data