Merge "Remove too aggressive DCHECKs."
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index ae3c4b0..4b4e549 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -2283,8 +2283,6 @@
   if (kIsDebugBuild) {
     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 2a281dd..3e6adcb 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -46,10 +46,10 @@
   return *cache;
 }
 
-// Returns true if klass is admissible to the propagation: non-null and non-erroneous.
+// Returns true if klass is admissible to the propagation: non-null and resolved.
 // 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() &&
+  return klass != nullptr && klass->IsResolved() &&
       (!klass->IsArrayClass() || IsAdmissible(klass->GetComponentType()));
 }
 
diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h
index 2894b68..0b3461f 100644
--- a/runtime/mirror/dex_cache-inl.h
+++ b/runtime/mirror/dex_cache-inl.h
@@ -55,7 +55,6 @@
 inline void DexCache::SetResolvedType(uint32_t type_idx, Class* resolved) {
   DCHECK_LT(type_idx, NumResolvedTypes());  // NOTE: Unchecked, i.e. not throwing AIOOB.
   // TODO default transaction support.
-  DCHECK(resolved == nullptr || !resolved->IsErroneous());
   GetResolvedTypes()[type_idx] = GcRoot<Class>(resolved);
   // TODO: Fine-grained marking, so that we don't need to go through all arrays in full.
   Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(this);
diff --git a/test/606-erroneous-class/expected.txt b/test/606-erroneous-class/expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/606-erroneous-class/expected.txt
diff --git a/test/606-erroneous-class/info.txt b/test/606-erroneous-class/info.txt
new file mode 100644
index 0000000..42cbb7a
--- /dev/null
+++ b/test/606-erroneous-class/info.txt
@@ -0,0 +1,3 @@
+Regression test for a DCHECK in the DexCache which prevented erroneous classes
+from being stored into it. This was bogus because the status of a class can be
+changed by another thread.
\ No newline at end of file
diff --git a/test/606-erroneous-class/smali-multidex/ClassA.smali b/test/606-erroneous-class/smali-multidex/ClassA.smali
new file mode 100644
index 0000000..f87fcb2
--- /dev/null
+++ b/test/606-erroneous-class/smali-multidex/ClassA.smali
@@ -0,0 +1,27 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+.class public final LClassA;
+.super Ljava/lang/Object;
+
+.method public static foo()V
+    .registers 1
+    # Obtain the ErrClass type from Dex cache of the first Dex file. Note that
+    # because the first Dex file has already been verified, we know the class
+    # is erroneous at this point.
+    sget-object v0, LClassB;->g:LErrClass;
+    # Use the object in a way that will try to store the ErrClass type in
+    # the Dex cache of the second Dex file.
+    invoke-virtual {v0}, LErrClass;->foo()V
+.end method
diff --git a/test/606-erroneous-class/smali/ClassB.smali b/test/606-erroneous-class/smali/ClassB.smali
new file mode 100644
index 0000000..80754c8
--- /dev/null
+++ b/test/606-erroneous-class/smali/ClassB.smali
@@ -0,0 +1,18 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+.class public LClassB;
+.super Ljava/lang/Object;
+
+.field public static g:LErrClass;
diff --git a/test/606-erroneous-class/smali/ErrClass.smali b/test/606-erroneous-class/smali/ErrClass.smali
new file mode 100644
index 0000000..740f1e1
--- /dev/null
+++ b/test/606-erroneous-class/smali/ErrClass.smali
@@ -0,0 +1,26 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+.class public final LErrClass;
+.super Ljava/lang/Object;
+
+.field public g:Ljava/lang/Object;
+
+.method public foo()V
+    .registers 6
+    # Use a new instance before initializing it => hard verifier error.
+    new-instance v0, LSomeClass;
+    iput-object v0, p0, LErrClass;->g:Ljava/lang/Object;
+    return-void
+.end method
diff --git a/test/606-erroneous-class/src/Main.java b/test/606-erroneous-class/src/Main.java
new file mode 100644
index 0000000..7dbe567
--- /dev/null
+++ b/test/606-erroneous-class/src/Main.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+  public static void main(String[] args) {
+    // Nothing to run.
+  }
+}