Fix constructor access check through reflection

We must not throw IllegalAccessException if the constructor has been
made accessible by a previous call to Constructor.setAccessible, even
if the caller cannot access the constructor.

Bug: 20639158

(cherry picked from commit 2d2f2a9c665b02ca5139f71e37ca5e08389e4191)

Change-Id: Ic5cb54256f11aefcfaa99f2ee85c4a32f30e693a
diff --git a/runtime/native/java_lang_reflect_Constructor.cc b/runtime/native/java_lang_reflect_Constructor.cc
index 810b354..908089e 100644
--- a/runtime/native/java_lang_reflect_Constructor.cc
+++ b/runtime/native/java_lang_reflect_Constructor.cc
@@ -36,7 +36,7 @@
  */
 static jobject Constructor_newInstance(JNIEnv* env, jobject javaMethod, jobjectArray javaArgs) {
   ScopedFastNativeObjectAccess soa(env);
-  mirror::Method* m = soa.Decode<mirror::Method*>(javaMethod);
+  mirror::Constructor* m = soa.Decode<mirror::Constructor*>(javaMethod);
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
   if (UNLIKELY(c->IsAbstract())) {
@@ -46,7 +46,7 @@
     return nullptr;
   }
   // Verify that we can access the class.
-  if (!c->IsPublic()) {
+  if (!m->IsAccessible() && !c->IsPublic()) {
     auto* caller = GetCallingClass(soa.Self(), 1);
     // If caller is null, then we called from JNI, just avoid the check since JNI avoids most
     // access checks anyways. TODO: Investigate if this the correct behavior.
diff --git a/test/100-reflect2/src/Main.java b/test/100-reflect2/src/Main.java
index 86a5ef8..72e14b1 100644
--- a/test/100-reflect2/src/Main.java
+++ b/test/100-reflect2/src/Main.java
@@ -266,7 +266,7 @@
     show(ctor.newInstance(new char[] { 'x', 'y', 'z', '!' }, 1, 2));
   }
 
-  private static void testPackagePrivate() {
+  private static void testPackagePrivateConstructor() {
     try {
       Class<?> c = Class.forName("sub.PPClass");
       Constructor cons = c.getConstructor();
@@ -280,10 +280,23 @@
     }
   }
 
+  private static void testPackagePrivateAccessibleConstructor() {
+    try {
+      Class<?> c = Class.forName("sub.PPClass");
+      Constructor cons = c.getConstructor();
+      cons.setAccessible(true);  // ensure we prevent IllegalAccessException
+      cons.newInstance();
+    } catch (Exception e) {
+      // Error.
+      e.printStackTrace();
+    }
+  }
+
   public static void main(String[] args) throws Exception {
     testFieldReflection();
     testMethodReflection();
     testConstructorReflection();
-    testPackagePrivate();
+    testPackagePrivateConstructor();
+    testPackagePrivateAccessibleConstructor();
   }
 }