This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hello, The Ada testcase attached is expected to compile and run silently. Built with "gnatmake -O2 -gnatp handle_and_return.adb" with a hppa1.1-hp-hpux11.00 compiler, it loops infinitely. The bad thing concentrates in this sequence: begin Raise_CE; return; exception when others => null; end; begin Raise_CE; return; exception when others => null; end; Each block features a call to a subprogram which raises an exception, expected to be caught by the associated block handler. What is happening is that the second exception propagates up to the first handler. This is related to an optimization performed by pa.c:output_call, in particular: /* This call has an unconditional jump in its delay slot. */ xoperands[0] = XEXP (PATTERN (NEXT_INSN (insn)), 1); if (!delay_slot_filled && INSN_ADDRESSES_SET_P ()) { /* See if the return address can be adjusted. Use the containing sequence insn's address. */ ... It optimizes a case where a call is immediatly followed by a jump, adjusting the return address to directly designate the jump destination. Comparing the assembly outputs for handle_and_return.adb for cases where this optimization is deactivated or performed, we observe a change like: L$EHB0000: L$CFI0003: .CALL bl _ada_raise_ce,%r2 <== First call/raise stw %r4,-120(%r30) L$EHE0000: L$0009: L$EHB0001: ldw -148(%r30),%r2 <== First return ... bv %r0(%r2) [...] L$EHB0004: .CALL bl _ada_raise_ce,%r2 <== Second raise - nop - b,n L$0009 <== Second return, branch to the First return sequence - replaced by ... + ldo L$0009-L$0023(%r2),%r2 <== return address adjustment in +L$0023: the call delay slot L$EHE0004: The initial post call branch aimed at the common return sequence is optimized into a return address adjustment. This badly confuses the unwinder while it propagates the second exception: it determines the region to which the second call is attached from the adjusted return address it sees and lands into the first call region. The attached patch addresses this by disabling the optimization as soon as we're generating eh frame tables, on the grounds that we need to maintain the usual return-address/corresponding-call-address relationship for table based exception propagation. We have been using a minor variant internally for a while. This resolution seems a bit brutal, though, and I suppose there might be a better way out, so I haven't yet performed the full testing cycle at this point. I'll happily do so if need be, of course. Thoughts ? Thanks in advance, With Kind Regards, Olivier 2009-04-27 Olivier Hainque <hainque@adacore.com> * config/pa/pa.c (output_call): Don't optimize post call jumps into return address adjustments when generating eh frame tables. testsuite/ * gnat.dg/raise_ce.adb: Helper for ... * gnat.dg/handle_and_return.adb: New test.
Attachment:
pa-output_call.dif
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |