8236697: Stack overflow with cyclic hierarchy in class file

Implemented minimal necessary cycle detection to avoid stack overflow in c.s.t.j.code.Types::asSuper

Reviewed-by: vromero
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
index 97df186..e1a57e8 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
@@ -2124,22 +2124,31 @@
                 if (t.tsym == sym)
                     return t;
 
-                Type st = supertype(t);
-                if (st.hasTag(CLASS) || st.hasTag(TYPEVAR)) {
-                    Type x = asSuper(st, sym);
-                    if (x != null)
-                        return x;
+                Symbol c = t.tsym;
+                if ((c.flags_field & LOCKED) != 0) {
+                    return null;
                 }
-                if ((sym.flags() & INTERFACE) != 0) {
-                    for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
-                        if (!l.head.hasTag(ERROR)) {
-                            Type x = asSuper(l.head, sym);
-                            if (x != null)
-                                return x;
+                try {
+                    c.flags_field |= LOCKED;
+                    Type st = supertype(t);
+                    if (st.hasTag(CLASS) || st.hasTag(TYPEVAR)) {
+                        Type x = asSuper(st, sym);
+                        if (x != null)
+                            return x;
+                    }
+                    if ((sym.flags() & INTERFACE) != 0) {
+                        for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
+                            if (!l.head.hasTag(ERROR)) {
+                                Type x = asSuper(l.head, sym);
+                                if (x != null)
+                                    return x;
+                            }
                         }
                     }
+                    return null;
+                } finally {
+                    c.flags_field &= ~LOCKED;
                 }
-                return null;
             }
 
             @Override
diff --git a/test/langtools/tools/javac/8236697/Cyclic.jcod b/test/langtools/tools/javac/8236697/Cyclic.jcod
new file mode 100644
index 0000000..def57c1
--- /dev/null
+++ b/test/langtools/tools/javac/8236697/Cyclic.jcod
@@ -0,0 +1,29 @@
+class Cyclic {
+  0xCAFEBABE;
+  0; // minor version
+  57; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    class #2; // #1
+    Utf8 "Cyclic"; // #2
+    class #4; // #3
+    Utf8 "java/lang/Object"; // #4
+  } // Constant Pool
+
+  0x0600; // access
+  #1;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+    #1;
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+  } // methods
+
+  [] { // Attributes
+  } // Attributes
+} // end class Cyclic
diff --git a/test/langtools/tools/javac/8236697/T8236697.java b/test/langtools/tools/javac/8236697/T8236697.java
new file mode 100644
index 0000000..ecf2205
--- /dev/null
+++ b/test/langtools/tools/javac/8236697/T8236697.java
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8236697
+ * @summary Stack overflow with cyclic hierarchy in class file
+ * @build Cyclic
+ * @compile/fail/ref=T8236697.out -XDrawDiagnostics T8236697.java
+ */
+interface T8236697 extends Iterable {
+
+    public Cyclic iterator();
+
+}
diff --git a/test/langtools/tools/javac/8236697/T8236697.out b/test/langtools/tools/javac/8236697/T8236697.out
new file mode 100644
index 0000000..eb2d4ed
--- /dev/null
+++ b/test/langtools/tools/javac/8236697/T8236697.out
@@ -0,0 +1,2 @@
+T8236697.java:10:19: compiler.err.override.incompatible.ret: (compiler.misc.clashes.with: iterator(), T8236697, iterator(), java.lang.Iterable), Cyclic, java.util.Iterator
+1 error
\ No newline at end of file