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 <[email protected]>
* 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
