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]

Re: More SJLJ exception breakage


On Thu, Apr 16, 2009 at 8:24 PM, Ulrich Weigand <uweigand@de.ibm.com> wrote:
> Hello,
>
> it seems SJLJ exception handling is broken again (at least on SPU). ?The
> most obvious symptom is that libstdc++ "operator new" is miscompiled.
>
> A reduced test case would be:
>
> typedef long unsigned int size_t;
> extern "C" void * malloc (size_t __size);
>
> class bad_alloc
> {
> ?public:
> ? ?bad_alloc() throw() { }
> ? ?virtual ~bad_alloc() throw();
> ? ?virtual const char* what() const throw();
> };
>
> void *
> operator new (size_t sz) throw (bad_alloc)
> {
> ?void *p;
>
> ?p = (void *) malloc (sz);
> ?if (p == 0)
> ? ?throw bad_alloc();
>
> ?return p;
> }
>
> Building this with -O2 results in:
>
> ? ? ? ?brsl ? ?$lr,malloc ? ? ?;# 7 ? ?_call_value/2 ? [length = 4]
> ? ? ? ?brz ? ? $3,.L8 ?;# 10 ? *spu.md:3590 ? ?[length = 4]
> #note result of malloc is in register $r3 ?(the branch goes to the throw case)
>
> ? ? ? ?ai ? ? ?$3,$sp,48 ? ? ? ;# 87 ? addsi3/2 ? ? ? ?[length = 4]
> ? ? ? ?brsl ? ?$lr,_Unwind_SjLj_Unregister ? ? ;# 88 ? _call/2 [length = 4]
> #which is clobbered here with the argument passed to _Unwind_SjLj_Unregister
>
> ? ? ? ?ai ? ? ?$sp,$sp,176 ? ? ;# 160 ?addsi3/2 ? ? ? ?[length = 4]
> ? ? ? ?lqd ? ? $lr,16($sp) ? ? ;# 162 ?_movv4si/5 ? ? ?[length = 4]
> ? ? ? ?lqd ? ? $127,-16($sp) ? ;# 161 ?_movv4si/5 ? ? ?[length = 4]
> ? ? ? ?bi ? ? ?$lr ? ? ;# 164 ?_return [length = 4]
> #and never restored on its way out
>
> The RTL is broken already in ...133r.eh:
>
> (code_label 32 31 41 10 1 "" [1 uses])
>
> (note 41 32 33 10 [bb 10] NOTE_INSN_BASIC_BLOCK)
>
> (insn 33 41 39 10 new_op.ii:23 (set (reg/i:SI 3 $3)
> ? ? ? ?(reg:SI 138 [ <result> ])) -1 (nil))
>
> (insn 39 33 86 10 new_op.ii:23 (use (reg/i:SI 3 $3)) -1 (nil))
>
> (insn 86 39 87 10 (set (reg:SI 186)
> ? ? ? ?(plus:SI (reg/f:SI 132 virtual-stack-vars)
> ? ? ? ? ? ?(const_int -112 [0xffffffffffffff90]))) -1 (nil))
>
> (insn 87 86 88 10 (set (reg:SI 3 $3)
> ? ? ? ?(reg:SI 186)) -1 (nil))
>
> (call_insn 88 87 0 10 (parallel [
> ? ? ? ? ? ?(call (mem:QI (symbol_ref:SI ("_Unwind_SjLj_Unregister") [flags 0x41]) [0 S1 A8])
> ? ? ? ? ? ? ? ?(const_int 0 [0x0]))
> ? ? ? ? ? ?(clobber (reg:SI 0 $lr))
> ? ? ? ? ? ?(clobber (reg:SI 130 hbr))
> ? ? ? ?]) -1 (expr_list:REG_EH_REGION (const_int 0 [0x0])
> ? ? ? ?(nil))
> ? ?(expr_list:REG_DEP_TRUE (use (reg:SI 3 $3))
> ? ? ? ?(nil)))
>
> It would appear the call to _Unwind_SjLj_Unregister is simply inserted
> too late; it needs to take place *before* the result register is set up
> (insn 33), not afterwards.
>
>
> Any idea why this might happen or suggestions what else to check?

Maybe fixed after http://gcc.gnu.org/ml/gcc-cvs/2009-04/msg00805.html?
Or needs a similar fix in the place wherever we handle SJLJ exceptions
in the middle-end?

Richard.

> Thanks,
> Ulrich
>
> --
> ?Dr. Ulrich Weigand
> ?GNU Toolchain for Linux on System z and Cell BE
> ?Ulrich.Weigand@de.ibm.com
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]