Fixes default method resolution (#159)
[jpf-core.git] / src / main / gov / nasa / jpf / vm / ClassInfo.java
index d9e5331..83b3f5b 100644 (file)
@@ -1091,17 +1091,21 @@ public class ClassInfo extends InfoObject implements Iterable<MethodInfo>, Gener
   public MethodInfo getDefaultMethod (String uniqueName) {
     MethodInfo mi = null;
     
   public MethodInfo getDefaultMethod (String uniqueName) {
     MethodInfo mi = null;
     
-    for (ClassInfo ci = this; ci != null; ci = ci.superClass){
-      for (ClassInfo ciIfc : ci.interfaces){
-        MethodInfo miIfc = ciIfc.getMethod(uniqueName, true);
-        if (miIfc != null && !miIfc.isAbstract()){
-          if (mi != null && !mi.equals(miIfc)){
+    for (ClassInfo ciIfc : this.getAllInterfaces()){
+      MethodInfo miIfc = ciIfc.getMethod(uniqueName, false);
+      if (miIfc != null && !miIfc.isAbstract() && !miIfc.isPrivate() && !miIfc.isStatic()){
+        if (mi != null && !mi.equals(miIfc)){
+          if(miIfc.getClassInfo().isSubInterfaceOf(mi.getClassInfo())) {
+            mi = miIfc;
+          } else if(mi.getClassInfo().isSubInterfaceOf(miIfc.getClassInfo())) {
+            continue;
+          } else {
             // this has to throw a IncompatibleClassChangeError in the client since Java prohibits ambiguous default methods
             String msg = "Conflicting default methods: " + mi.getFullName() + ", " + miIfc.getFullName();
             throw new ClassChangeException(msg);
             // this has to throw a IncompatibleClassChangeError in the client since Java prohibits ambiguous default methods
             String msg = "Conflicting default methods: " + mi.getFullName() + ", " + miIfc.getFullName();
             throw new ClassChangeException(msg);
-          } else {
-            mi = miIfc;
           }
           }
+        } else {
+          mi = miIfc;
         }
       }
     }
         }
       }
     }
@@ -1109,6 +1113,11 @@ public class ClassInfo extends InfoObject implements Iterable<MethodInfo>, Gener
     return mi;
   }
   
     return mi;
   }
   
+  private boolean isSubInterfaceOf(ClassInfo classInfo) {
+    assert this.isInterface() && classInfo.isInterface();
+    return this == classInfo || this.getAllInterfaces().contains(classInfo);
+  }
+
   /**
    * This retrieves the SAM from this functional interface. Note that this is only
    * called on functional interface expecting to have a SAM. This shouldn't expect 
   /**
    * This retrieves the SAM from this functional interface. Note that this is only
    * called on functional interface expecting to have a SAM. This shouldn't expect