ART: Change RETURN_OBJECT verification for arrays
Arrays appear to be valid (as according to spec), even if their
components are erroneous. If a component is erroneous, it may not
have loaded superclass or interface information, and so fail a
direct check for assignability.
Add a cutout that checks whether the declared return-type or the
actual return-type are arrays with erroneous components (and if so,
have the same 'depth'). In that case, generate a soft instead of a
hard error.
Also includes a fix to DumpClass.
Bug: 19683465
Change-Id: Ie73de03adeb0af7e939370d7363684fe125d7994
diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc
index 201169f..97d0cbe 100644
--- a/runtime/verifier/reg_type.cc
+++ b/runtime/verifier/reg_type.cc
@@ -822,5 +822,42 @@
return os;
}
+bool RegType::CanAssignArray(const RegType& src, RegTypeCache& reg_types,
+ Handle<mirror::ClassLoader> class_loader, bool* soft_error) const {
+ if (!IsArrayTypes() || !src.IsArrayTypes()) {
+ *soft_error = false;
+ return false;
+ }
+
+ const RegType& cmp1 = reg_types.GetComponentType(*this, class_loader.Get());
+ const RegType& cmp2 = reg_types.GetComponentType(src, class_loader.Get());
+
+ if (cmp1.IsAssignableFrom(cmp2)) {
+ return true;
+ }
+ if (cmp1.IsUnresolvedTypes()) {
+ if (cmp2.IsIntegralTypes() || cmp2.IsFloatTypes() || cmp2.IsArrayTypes()) {
+ *soft_error = false;
+ return false;
+ }
+ *soft_error = true;
+ return false;
+ }
+ if (cmp2.IsUnresolvedTypes()) {
+ if (cmp1.IsIntegralTypes() || cmp1.IsFloatTypes() || cmp1.IsArrayTypes()) {
+ *soft_error = false;
+ return false;
+ }
+ *soft_error = true;
+ return false;
+ }
+ if (!cmp1.IsArrayTypes() || !cmp2.IsArrayTypes()) {
+ *soft_error = false;
+ return false;
+ }
+ return cmp1.CanAssignArray(cmp2, reg_types, class_loader, soft_error);
+}
+
+
} // namespace verifier
} // namespace art