Cleanup return type checks with arrays.
It's always a hard fail if array classes are not assignable.
Test: test.py
Bug: 28313047
Change-Id: Ia471681cac531b53d1dc29111a6d04b1fd5b61ad
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 23d4de0..db1940c 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -2179,21 +2179,14 @@
Fail(VERIFY_ERROR_UNRESOLVED_TYPE_CHECK)
<< " can't resolve returned type '" << return_type << "' or '" << reg_type << "'";
} else {
- bool soft_error = false;
// Check whether arrays are involved. They will show a valid class status, even
// if their components are erroneous.
if (reg_type.IsArrayTypes() && return_type.IsArrayTypes()) {
- return_type.CanAssignArray(reg_type, reg_types_, class_loader_, this, &soft_error);
- if (soft_error) {
- Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "array with erroneous component type: "
- << reg_type << " vs " << return_type;
+ if (!return_type.CanAssignArray(reg_type, reg_types_, class_loader_, this)) {
+ Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning '" << reg_type
+ << "', but expected from declaration '" << return_type << "'";
}
}
-
- if (!soft_error) {
- Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning '" << reg_type
- << "', but expected from declaration '" << return_type << "'";
- }
}
}
}
diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc
index 5af2d4b..3891f21 100644
--- a/runtime/verifier/reg_type.cc
+++ b/runtime/verifier/reg_type.cc
@@ -1035,18 +1035,10 @@
bool RegType::CanAssignArray(const RegType& src,
RegTypeCache& reg_types,
Handle<mirror::ClassLoader> class_loader,
- MethodVerifier* verifier,
- bool* soft_error) const {
+ MethodVerifier* verifier) const {
+ DCHECK(!IsUnresolvedMergedReference());
+ DCHECK(!src.IsUnresolvedMergedReference());
if (!IsArrayTypes() || !src.IsArrayTypes()) {
- *soft_error = false;
- return false;
- }
-
- if (IsUnresolvedMergedReference() || src.IsUnresolvedMergedReference()) {
- // An unresolved array type means that it's an array of some reference type. Reference arrays
- // can never be assigned to primitive-type arrays, and vice versa. So it is a soft error if
- // both arrays are reference arrays, otherwise a hard error.
- *soft_error = IsObjectArrayTypes() && src.IsObjectArrayTypes();
return false;
}
@@ -1058,25 +1050,20 @@
}
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, verifier, soft_error);
+ return cmp1.CanAssignArray(cmp2, reg_types, class_loader, verifier);
}
const NullType* NullType::CreateInstance(ObjPtr<mirror::Class> klass,
diff --git a/runtime/verifier/reg_type.h b/runtime/verifier/reg_type.h
index e8a7a80..5245591 100644
--- a/runtime/verifier/reg_type.h
+++ b/runtime/verifier/reg_type.h
@@ -222,15 +222,11 @@
// Can this array type potentially be assigned by src.
// This function is necessary as array types are valid even if their components types are not,
// e.g., when they component type could not be resolved. The function will return true iff the
- // types are assignable. It will return false otherwise. In case of return=false, soft_error
- // will be set to true iff the assignment test failure should be treated as a soft-error, i.e.,
- // when both array types have the same 'depth' and the 'final' component types may be assignable
- // (both are reference types).
+ // types assignable. It will return false otherwise.
bool CanAssignArray(const RegType& src,
RegTypeCache& reg_types,
Handle<mirror::ClassLoader> class_loader,
- MethodVerifier* verifier,
- bool* soft_error) const
+ MethodVerifier* verifier) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Can this type be assigned by src? Variant of IsAssignableFrom that doesn't