Fix issue with IMT dispatch.

If a default and an abstract method map to the same IMT slot one could
end up invoking the default method when one invokes the abstract
method.

Bug: 24618811
Bug: 26827549

Change-Id: I2ccb8e8b5362eb4961531b63e7b946ad8ef936a6
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index bb709e8..080cfb4 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -6245,15 +6245,7 @@
           }  // case kAbstractFound
         }
         if (LIKELY(fill_tables)) {
-          if (current_method != nullptr) {
-            // We found a default method implementation. Record it in the iftable and IMT.
-            method_array->SetElementPtrSize(j, current_method, image_pointer_size_);
-            SetIMTRef(unimplemented_method,
-                      imt_conflict_method,
-                      image_pointer_size_,
-                      current_method,
-                      /*out*/imt_ptr);
-          } else if (!super_interface) {
+          if (current_method == nullptr && !super_interface) {
             // We could not find an implementation for this method and since it is a brand new
             // interface we searched the entire vtable (and all default methods) for an
             // implementation but couldn't find one. We therefore need to make a miranda method.
@@ -6269,7 +6261,17 @@
               new(miranda_method) ArtMethod(interface_method, image_pointer_size_);
               miranda_methods.push_back(miranda_method);
             }
-            method_array->SetElementPtrSize(j, miranda_method, image_pointer_size_);
+            current_method = miranda_method;
+          }
+
+          if (current_method != nullptr) {
+            // We found a default method implementation. Record it in the iftable and IMT.
+            method_array->SetElementPtrSize(j, current_method, image_pointer_size_);
+            SetIMTRef(unimplemented_method,
+                      imt_conflict_method,
+                      image_pointer_size_,
+                      current_method,
+                      /*out*/imt_ptr);
           }
         }
       }  // For each method in interface end.