Fix vtable corruption.
Due to failing to keep track of superclass implementations of
interface methods we could end up in situations where methods were
placed onto a class's vtable multiple times. This could cause virtual
and interface dispatches on subclasses to fail by causing corruption
of the subclass's vtable and iftable.
Bug: 28333278
Change-Id: I37d9740ca912daf37cdf9ff82697bbc5db46177a
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index a147aba..d29d33a 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -6635,6 +6635,15 @@
// The method is not overridable by a default method (i.e. it is directly implemented
// in some class). Therefore move onto the next interface method.
continue;
+ } else {
+ // If the super-classes method is override-able by a default method we need to keep
+ // track of it since though it is override-able it is not guaranteed to be 'overridden'.
+ // If it turns out not to be overridden and we did not keep track of it we might add it
+ // to the vtable twice, causing corruption in this class and possibly any subclasses.
+ DCHECK(vtable_impl == nullptr || vtable_impl == supers_method)
+ << "vtable_impl was " << PrettyMethod(vtable_impl) << " and not 'nullptr' or "
+ << PrettyMethod(supers_method) << " as expected. IFTable appears to be corrupt!";
+ vtable_impl = supers_method;
}
}
// If we haven't found it yet we should search through the interfaces for default methods.