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]

PR middle-end/21362: ICE in make_edges, at cfgbuild.c:327


This happens when an exception region has a label that gets deleted;
this in turn happens because the handler is unreachable.

Here's the original Java code:

        ObjectOutputStream oos = null;
        try {
            fos = new FileOutputStream(file.getAbsolutePath());
            oos = new ObjectOutputStream(new BufferedOutputStream(fos));
        } catch (IOException e) {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException f) {
                    ;
                }
            }
            throw e;
        }

Note that (oos != null) is impossible: if an exception occurs during
the try block the variable oos will not be assigned, so will be null.
As a consequence of this, the block

                try {
                    oos.close();
                } catch (IOException f) {
                    ;
                }

is unreachable, and is deleted.  Unfortunately, this happens after
tree-eh has tidied up its EH regions, and we're left with a handler
that has a label, no statments in its catch block, and no statments in
its try block.  Later on, we delete the label for this unreachable
handler while we're merging adjacent blocks.  However, we don't remove
the associated exception handler so things go bang in make_edges.

As far as I can see, this will only happen with Java, because only
Java has catch blocks that contain only gotos; the gotos that fall
through are deleted, leaving only an empty catch region.

The easiest way to solve this is to check if an insn is the label for
a handler whenever deleting insns.  An alternative might be to call
maybe_remove_eh_handler() from rtl_merge_blocks(), but I can't be
certain that will fix every possible case.

Tested bootstrap + libjava + libstdc++ testsuites.

Andrew.



2005-05-05  Andrew Haley  <aph@redhat.com>

	* cfgrtl.c (delete_insn): Call maybe_remove_eh_handler if INSN is
	a label.

Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgrtl.c,v
retrieving revision 1.171
diff -u -c -r1.171 cfgrtl.c
cvs diff: conflicting specifications of output style
*** cfgrtl.c	25 Apr 2005 12:46:05 -0000	1.171
--- cfgrtl.c	5 May 2005 13:29:13 -0000
***************
*** 132,137 ****
--- 132,142 ----
  	}
  
        remove_node_from_expr_list (insn, &nonlocal_goto_handler_labels);
+       
+       /* This might be the label for an exception handler which can't
+ 	 be reached.  We need to remove the label from the
+ 	 exception_handler_label list.  */
+       maybe_remove_eh_handler (insn);
      }
  
    if (really_delete)


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