Test component type for errors too.
With regression test.
Rationale:
Moved erroneous check in convenience method, so we
put all the same logic in one place. When testing
for erroneous T[], check both the array type
as well at the component type T for errors
(it is possible T[] is not marked erroneous
even though T is eventually).
BUG=28358598
Change-Id: I11339a976dc83e0493a99e6bb97f3a058ca3f796
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index fe75451..6703695 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -2218,6 +2218,7 @@
ScopedObjectAccess soa(Thread::Current());
DCHECK(IsValidHandle(type_handle));
DCHECK(!type_handle->IsErroneous());
+ DCHECK(!type_handle->IsArrayClass() || !type_handle->GetComponentType()->IsErroneous());
if (!is_exact) {
DCHECK(!type_handle->CannotBeAssignedFromOtherTypes())
<< "Callers of ReferenceTypeInfo::Create should ensure is_exact is properly computed";
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc
index 04c9ff9..7e1fd75 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -46,6 +46,13 @@
return *cache;
}
+// Returns true if klass is admissible to the propagation: non-null and non-erroneous.
+// For an array type, we also check if the component type is admissible.
+static bool IsAdmissible(mirror::Class* klass) SHARED_REQUIRES(Locks::mutator_lock_) {
+ return klass != nullptr && !klass->IsErroneous() &&
+ (!klass->IsArrayClass() || IsAdmissible(klass->GetComponentType()));
+}
+
ReferenceTypeInfo::TypeHandle ReferenceTypePropagation::HandleCache::GetObjectClassHandle() {
return GetRootHandle(handles_, ClassLinker::kJavaLangObject, &object_class_handle_);
}
@@ -453,15 +460,10 @@
}
instr->SetReferenceTypeInfo(
ReferenceTypeInfo::Create(handle_cache_->GetStringClassHandle(), /* is_exact */ true));
- } else if (klass != nullptr) {
- if (klass->IsErroneous()) {
- // Set inexact object type for erroneous types.
- instr->SetReferenceTypeInfo(instr->GetBlock()->GetGraph()->GetInexactObjectRti());
- } else {
- ReferenceTypeInfo::TypeHandle handle = handle_cache_->NewHandle(klass);
- is_exact = is_exact || handle->CannotBeAssignedFromOtherTypes();
- instr->SetReferenceTypeInfo(ReferenceTypeInfo::Create(handle, is_exact));
- }
+ } else if (IsAdmissible(klass)) {
+ ReferenceTypeInfo::TypeHandle handle = handle_cache_->NewHandle(klass);
+ is_exact = is_exact || handle->CannotBeAssignedFromOtherTypes();
+ instr->SetReferenceTypeInfo(ReferenceTypeInfo::Create(handle, is_exact));
} else {
instr->SetReferenceTypeInfo(instr->GetBlock()->GetGraph()->GetInexactObjectRti());
}
@@ -563,7 +565,7 @@
instr->GetDexFile(),
instr->GetTypeIndex(),
hint_dex_cache_);
- if (resolved_class != nullptr && !resolved_class->IsErroneous()) {
+ if (IsAdmissible(resolved_class)) {
instr->SetLoadedClassRTI(ReferenceTypeInfo::Create(
handle_cache_->NewHandle(resolved_class), /* is_exact */ true));
}
@@ -742,7 +744,7 @@
}
Handle<mirror::Class> handle = parent_rti.GetTypeHandle();
- if (handle->IsObjectArrayClass() && !handle->GetComponentType()->IsErroneous()) {
+ if (handle->IsObjectArrayClass() && IsAdmissible(handle->GetComponentType())) {
ReferenceTypeInfo::TypeHandle component_handle =
handle_cache->NewHandle(handle->GetComponentType());
bool is_exact = component_handle->CannotBeAssignedFromOtherTypes();