gen_exception_label allocates handler labels from wrong obstack
Godmar Back
gback@cs.utah.edu
Sun Dec 5 15:56:00 GMT 1999
Hi,
In except.c, gen_exception_label reads:
/* get an exception label. These must be on the permanent obstack */
rtx
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