This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


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

Java: Fix cyclic inheritance detection problem


Here's something I picked up running jacks on the current GCJ. Code
like the following is causing GCJ to loop forever:

class X extends X {};

Although GCJ has a mechanism to detect cyclic inheritance, it isn't
working in most cases. Possibly this was broken with the multifile
compilation changes, or maybe it was broken even before that. In any
case, the issue is that do_resolve_class, which is called from
java_complete_class, looks at super classes during inner class
resolution to determine if an unqualified class being resolved is a
member of an enclosing supercontext. However, java_complete_class is
called before the existing cyclic inheritance check,
java_check_circular_reference. But java_check_circular_reference can't
be called until the class is fully resolved: catch 22.

Actually, its not clear to me why resolve_class() is called with an
"enclosing" argument at all here, because X is not an inner class, but
I can imagine there are situations where this patch would be required
even if that wasnt the case.

jacks results for the current 3.0 compiler:

gcj:    Total   1735    Passed  1380    Skipped 16      Failed  339

FWIW, this is a list of jacks test result changes since 2001-02-17
(with new tests ommitted):

14.20-try-7 {FAILED PASSED}
14.20-try-9 {PASSED FAILED}
14.20-try-10 {PASSED FAILED}
14.20-try-12 {FAILED PASSED}
14.20-try-25 {FAILED PASSED}
14.20-try-27 {PASSED FAILED}
14.20-try-28 {PASSED FAILED}
8.1.3-circular-2 {PASSED FAILED}
8.8.7-inaccessible-default-constructor-toplevel-2 {PASSED FAILED}
16.2.8-unassigned-6 {PASSED FAILED}
15.9.1-unqualified-anonymous-5 {FAILED PASSED}
15.9.1-unqualified-anonymous-8 {FAILED PASSED}
15.9.1-unqualified-anonymous-15 {FAILED PASSED}
15.9.1-unqualified-anonymous-18 {FAILED PASSED}
15.28-simple-name-9 {FAILED PASSED}
15.28-string-17 {PASSED FAILED}
3.10.2-round-6 {PASSED FAILED}
6.6.1-8 {PASSED FAILED}
6.6.1-11 {PASSED FAILED}

The 8.1.3 regression is unrelated to this patch.

ok to commit?

regards

  [ bryce ]

2001-04-27  Bryce McKinlay  <bryce@waitaki.otago.ac.nz>

	* parse.y (do_resolve_class): Check for cyclic inheritance during
	inner class resolution. 

Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.251.2.19
diff -u -r1.251.2.19 parse.y
--- parse.y	2001/04/26 19:43:48	1.251.2.19
+++ parse.y	2001/04/27 11:11:42
@@ -5517,13 +5517,14 @@
 do_resolve_class (enclosing, class_type, decl, cl)
      tree enclosing, class_type, decl, cl;
 {
-  tree new_class_decl;
+  tree new_class_decl, super, start;
 
   /* Do not try to replace TYPE_NAME (class_type) by a variable, since
      it is changed by find_in_imports{_on_demand} and (but it doesn't
      really matter) qualify_and_find */
 
   /* 0- Search in the current class as an inner class */
+  start = enclosing;
 
   /* Maybe some code here should be added to load the class or
      something, at least if the class isn't an inner class and ended
@@ -5546,14 +5547,28 @@
 	}
 
       /* Now go to the upper classes, bail out if necessary. */
-      enclosing = CLASSTYPE_SUPER (TREE_TYPE (enclosing));
-      if (!enclosing || enclosing == object_type_node)
+      super = CLASSTYPE_SUPER (TREE_TYPE (enclosing));
+      if (!super || super == object_type_node)
         break;
 
-      if (TREE_CODE (enclosing) == POINTER_TYPE)
-	enclosing = do_resolve_class (NULL, enclosing, NULL, NULL);
+      if (TREE_CODE (super) == POINTER_TYPE)
+	super = do_resolve_class (NULL, super, NULL, NULL);
       else
-        enclosing = TYPE_NAME (enclosing);
+        super = TYPE_NAME (super);
+
+      /* We may not have checked for circular inheritance yet, so do so 
+	 here to prevent an infinite loop. */
+      if (super == start)
+	{
+	  if (!cl)
+	    cl = lookup_cl (decl);
+
+	  parse_error_context 
+	    (cl, "Cyclic inheritance involving %s", 
+	    IDENTIFIER_POINTER (DECL_NAME (enclosing)));
+	  break;
+	}
+      enclosing = super;
     }
 
   /* 1- Check for the type in single imports. This will change

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