This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Win32/SJLJ/Java interaction (aka: VICTORY!)
- From: Adam Megacz <gcj at lists dot megacz dot com>
- To: java at gcc dot gnu dot org
- Cc: jason at redhat dot com
- Date: 06 Mar 2002 12:54:09 -0800
- Subject: Win32/SJLJ/Java interaction (aka: VICTORY!)
- Organization: Myself
Background (for Jason):
As I've explained before, I checked out a copy of the gcc tree on
12-Dec in order to make libgcj work on mingw32. I am now trying
to patch my changes back to the trunk (and 3.1 branch, if time
permits).
After patching over all my changes, I noticed that at certain times
(notably in main()), throwing an exception would cause
_Unwind_SjLj_RaiseException to CALL to an invalid address when
attempting to invoke the EH personality function. This only happened
in the updated tree, not in the fork from 12-Dec.
Fast forward to a week ago...
Since I don't understand how the front end works at all, I've had to
spend the last six days tediously 'cvs update'-ing my workspace back
and forth in a binary search, doing clean builds, trying to find the
date on which the change was made which caused the problem. I have
finally narrowed it down to this ChangeLog entry:
2001-12-12 Jason Merrill <jason@redhat.com>
* semantics.c (genrtl_start_function): Don't pass
parms_have_cleanups or push an extra binding level.
(genrtl_finish_function): Lose cleanup_label cruft.
(Thank goodness I checked out my tree just before this patch went in!
If I had checked out a workspace just one day later, I wouldn't have
known to try rolling the repository back and forward!)
Jason, at the time you made this change, mingw-gcj didn't work at all,
so there's no way you could have known -- please understand that I'm
not blaming you, I just figured you might be able to shed some light
on what happened, which is why I'm CC'ing you on this email.
The patch at the end of this email un-does part of the aforementioned
ChangeLog entry, and causes exceptions to work again in
mingw-gcj-sjlj. Unfortunately, I have no idea why.
To Jason and java@gcc: do you know why this works? Can anybody fix
this "the right way", or can I check in my unpatch? (probably not,
since I don't know how or why it works)
Thanks, I'm in way over my head on this one, but hopefully I've done
enough of the grunt work to clear the way for people more familiar
with this part of gcc.
Speedy resolution would be appreciated; if this and the jc1 segfault
get fixed in the trunk/branch, I'll throw myself 100% into getting
mingw-gcj working for 3.1. Otherwise I really need to start devoting
more time to XWT; I've been neglecting it pretty badly and people are
clamoring for source code.
- a
Index: semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.252
diff -u -r1.252 semantics.c
--- semantics.c 2002/02/22 17:42:19 1.252
+++ semantics.c 2002/03/06 20:01:37
@@ -2550,6 +2550,7 @@
genrtl_finish_function (fn)
tree fn;
{
+ tree no_return_label = NULL_TREE;
tree t;
#if 0
@@ -2578,10 +2579,59 @@
/* Clean house because we will need to reorder insns here. */
do_pending_stack_adjust ();
- /* If we have a named return value, we need to force a return so that
- the return register is USEd. */
- if (DECL_NAME (DECL_RESULT (fn)))
+ if (!dtor_label && !DECL_CONSTRUCTOR_P (fn)
+ && return_label != NULL_RTX
+ && ! DECL_NAME (DECL_RESULT (current_function_decl)))
+ no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+
+ /* If this function is supposed to return a value, ensure that
+ we do not fall into the cleanups by mistake. The end of our
+ function will look like this:
+
+ user code (may have return stmt somewhere)
+ goto no_return_label
+ cleanup_label:
+ cleanups
+ goto return_label
+ no_return_label:
+ NOTE_INSN_FUNCTION_END
+ return_label:
+ things for return
+
+ If the user omits a return stmt in the USER CODE section, we
+ will have a control path which reaches NOTE_INSN_FUNCTION_END.
+ Otherwise, we won't. */
+ if (no_return_label)
+ {
+ DECL_CONTEXT (no_return_label) = fn;
+ DECL_INITIAL (no_return_label) = error_mark_node;
+ DECL_SOURCE_FILE (no_return_label) = input_filename;
+ DECL_SOURCE_LINE (no_return_label) = lineno;
+ expand_goto (no_return_label);
+ }
+
+ if (cleanup_label)
+ {
+ /* Remove the binding contour which is used to catch
+ cleanup-generated temporaries. */
+ expand_end_bindings (0, 0, 0);
+ poplevel (0, 0, 0);
+
+ /* Emit label at beginning of cleanup code for parameters. */
+ emit_label (cleanup_label);
+ }
+
+ /* Finish building code that will trigger warnings if users forget
+ to make their functions return values. */
+ if (return_label)
emit_jump (return_label);
+ if (no_return_label)
+ {
+ /* We don't need to call `expand_*_return' here because we don't
+ need any cleanups here--this path of code is only for error
+ checking purposes. */
+ expand_label (no_return_label);
+ }
/* We hard-wired immediate_size_expand to zero in start_function.
Expand_function_end will decrement this variable. So, we set the