gen_exception_label allocates handler labels from wrong obstack

Godmar Back
Sun Dec 5 15:56:00 GMT 1999


In except.c, gen_exception_label reads:

    /* get an exception label. These must be on the permanent obstack */

    gen_exception_label ()
      rtx lab;
      lab = gen_label_rtx ();
      return lab;

gen_label_rtx is implemented in a way that allocates the label from
the current rtl_stack.

It seems to me that for gen_exception_label to work properly, it must hold 
that rtl_stack == &permanent_obstack.

I have found that for the Java front-end at least, this property almost 
never holds (it holds only for the initial call from init_eh.)

As a result, the rtx's of exception handler labels are being freed after 
each function, causing dangling pointers.  As a temporary work-around,
I applied the patch below.  While it fixes the problem I was seeing, this
may not be the right fix for the problem; in any event, I recommend
putting an "assert()" whenever assumptions about the call environment
such as in this case are being made.

The problem manifested itself when I noticed that gcj would "forget"
to emit entries in its __EXCEPTION_TABLE__ for a given catch clause,
even though the start/end labels and the handlers themselves were emitted 
just fine.
I noticed that gen_exception_label would return the same address twice.
The delete_block() dead code eliminator would then remove the second label 
when compiling a later function, causing this handler to be removed
from all regions.  It would then be skipped when the __EXCEPTION_TABLE__
was emitted, resulting in an erroneous exception table and in turn in
erroneous execution.

	- Godmar

Index: except.c
RCS file: /cvs/gcc/egcs/gcc/except.c,v
retrieving revision 1.108
diff -u -r1.108 except.c
--- except.c	1999/11/25 20:06:25	1.108
+++ except.c	1999/12/05 23:24:23
@@ -571,7 +571,12 @@
 gen_exception_label ()
   rtx lab;
+  extern struct obstack *rtl_obstack;
+  struct obstack *tmp_rtl_obstack = rtl_obstack;
+  rtl_obstack = &permanent_obstack;
   lab = gen_label_rtx ();
+  rtl_obstack = tmp_rtl_obstack;
   return lab;

More information about the Gcc-bugs mailing list