Do not FixupStaticTrampolines of uninitialized classes

Bug: 13027732
Change-Id: I5966d63afd8fbcd091801297290f117f3c9cb44c
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index f8a20d0..fa50324 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1684,6 +1684,7 @@
 }
 
 void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) {
+  DCHECK(klass->IsInitialized()) << PrettyDescriptor(klass);
   if (klass->NumDirectMethods() == 0) {
     return;  // No direct methods => no static methods.
   }
@@ -3159,9 +3160,6 @@
     }
   }
 
-  // Opportunistically set static method trampolines to their destination.
-  FixupStaticTrampolines(klass.get());
-
   uint64_t t1 = NanoTime();
 
   bool success = true;
@@ -3185,6 +3183,8 @@
         ClassHelper kh(klass.get());
         LOG(INFO) << "Initialized class " << kh.GetDescriptor() << " from " << kh.GetLocation();
       }
+      // Opportunistically set static method trampolines to their destination.
+      FixupStaticTrampolines(klass.get());
     }
   }
   return success;
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 4c2bdb0..cba221d 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -41,7 +41,7 @@
 inline Class* Class::GetSuperClass() {
   // Can only get super class for loaded classes (hack for when runtime is
   // initializing)
-  DCHECK(IsLoaded() || !Runtime::Current()->IsStarted()) << IsLoaded();
+  DCHECK(IsLoaded() || IsErroneous() || !Runtime::Current()->IsStarted()) << IsLoaded();
   return GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_), false);
 }
 
diff --git a/test/084-class-init/expected.txt b/test/084-class-init/expected.txt
index 1389214..d7a80bf 100644
--- a/test/084-class-init/expected.txt
+++ b/test/084-class-init/expected.txt
@@ -8,3 +8,5 @@
 MethodThread message
 Fields (child thread): 111222333444
 Fields (main thread): 111222333444
+checkStaticMethodInvokeAfterFailedClinit START
+checkStaticMethodInvokeAfterFailedClinit PASSED
diff --git a/test/084-class-init/src/Main.java b/test/084-class-init/src/Main.java
index cf69570..28eb3e9 100644
--- a/test/084-class-init/src/Main.java
+++ b/test/084-class-init/src/Main.java
@@ -37,6 +37,7 @@
     public static void main(String[] args) {
         checkExceptions();
         checkTiming();
+        checkStaticMethodInvokeAfterFailedClinit();
     }
 
     public static void sleep(int msec) {
@@ -128,4 +129,33 @@
             SlowInit.printMsg("MethodThread message");
         }
     }
+
+    static void checkStaticMethodInvokeAfterFailedClinit() {
+        System.out.println("checkStaticMethodInvokeAfterFailedClinit START");
+
+        // Call static method to cause implicit clinit.
+        try {
+            ClassWithThrowingClinit.staticMethod();
+            System.out.println("checkStaticMethodInvokeAfterFailedClinit FAILED"
+                               + " due to missing ExceptionInInitializerError");
+        } catch (ExceptionInInitializerError expected) {
+        }
+
+        // Call again to make sure we still get the expected error.
+        try {
+            ClassWithThrowingClinit.staticMethod();
+            System.out.println("checkStaticMethodInvokeAfterFailedClinit FAILED"
+                               + " due to missing NoClassDefFoundError");
+        } catch (NoClassDefFoundError expected) {
+        }
+        System.out.println("checkStaticMethodInvokeAfterFailedClinit PASSED");
+    }
+
+    static class ClassWithThrowingClinit {
+        static {
+            throwDuringClinit();
+        }
+        static void staticMethod() {
+        }
+    }
 }