The program below doesn't exit with 0 as expected when it's compiled
with -O2.  It works fine with -O1 or -O2 -fno-delayed-branch.

--
int *dummy;

void
bar (int *p)
{
  dummy = p;
}

void
foo (int x)
{
  int var;

  bar (&var);
  if (x)
    throw 1;
}

int
main ()
{ 
  try {
    foo (1);
  } catch (...) {
    return 0;
  }
  return 1;
}
--

With -O2, the function foo looks like:

_Z3fooi:
.LFB3:
        mov.l   r8,@-r15
.LCFI3:
        mov     r4,r8
        mov.l   r14,@-r15
.LCFI4:
        sts.l   pr,@-r15
.LCFI5:
        mov.l   .L11,r1
        add     #-4,r15
.LCFI6:
        mov     r15,r14
.LCFI7:
        jsr     @r1
        mov     r14,r4
        tst     r8,r8
        bf/s    .L10
        add     #4,r14
        mov     r14,r15
        lds.l   @r15+,pr
        mov.l   @r15+,r14
        rts     
        mov.l   @r15+,r8
        .align 5
.L10:
        mov.l   .L12,r0
        jsr     @r0
        mov     #4,r4
        mov     #1,r1
        mov.l   r1,@r0
        mov.l   .L13,r1
        mov     r0,r4
        mov.l   .L14,r5
        jsr     @r1
        mov     #0,r6
        ...

Thus the throw part starting with .L10 is called after the excution of
"add #4,r14" in the delayed slot.  It seems that this doesn't match
the frame info of foo:

$ readelf -a ./a.out | grep foo
    99: 00400760   100 FUNC    GLOBAL DEFAULT   11 _Z3fooi

$ readelf --debug-dump=frames ./a.out
The section .eh_frame contains:
...
0000001c 00000028 00000020 FDE cie=00000000 pc=00400760..004007c4
  Augmentation data:     00 00 00 00

  DW_CFA_advance_loc: 2 to 00400762
  DW_CFA_def_cfa_offset: 4
  DW_CFA_offset: r8 at cfa-4
  DW_CFA_advance_loc: 4 to 00400766
  DW_CFA_def_cfa_offset: 8
  DW_CFA_advance_loc: 2 to 00400768
  DW_CFA_def_cfa_offset: 12
  DW_CFA_advance_loc: 4 to 0040076c
  DW_CFA_def_cfa_offset: 16
  DW_CFA_offset: r17 at cfa-12
  DW_CFA_offset: r14 at cfa-8
  DW_CFA_advance_loc: 2 to 0040076e
  DW_CFA_def_cfa_reg: r14
  DW_CFA_nop
  DW_CFA_nop

which assumes that r14 points the bottom of the frame when the throw
part is called.

-- 
           Summary: [4.0.0] SH: wrong code for EH
           Product: gcc
           Version: 4.0.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: target
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: kkojima at gcc dot gnu dot org
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: sh4-unknown-linux-gnu
  GCC host triplet: sh4-unknown-linux-gnu
GCC target triplet: sh4-unknown-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18032

Reply via email to