diff options
author | 2019-08-02 13:59:27 +0100 | |
---|---|---|
committer | 2019-08-05 19:27:58 +0000 | |
commit | 38a062eb7390f07ee0a318517f71d9b56491a5f7 (patch) | |
tree | 67204f1fbc785b888f9d5718e31cf22de6b2d727 | |
parent | e80ecf31e0d58a90d6b2a1d65ec090c03abc86dc (diff) |
Weaken 2 DCHECK()s in reflection.
Reflection can be used on classes that are being initialized
rather than just classes that are already initialized as we
were previously asserting.
Test: Additional tests in 100-reflect2.
Change-Id: I072c28533e9248856b49fddb4bc46109448ee8a9
-rw-r--r-- | runtime/native/java_lang_reflect_Field.cc | 2 | ||||
-rw-r--r-- | runtime/reflection.cc | 2 | ||||
-rw-r--r-- | test/100-reflect2/src/Main.java | 62 |
3 files changed, 64 insertions, 2 deletions
diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc index f21ded9c23..31734a4707 100644 --- a/runtime/native/java_lang_reflect_Field.cc +++ b/runtime/native/java_lang_reflect_Field.cc @@ -256,7 +256,7 @@ ALWAYS_INLINE inline static void SetFieldValue(ObjPtr<mirror::Object> o, bool allow_references, const JValue& new_value) REQUIRES_SHARED(Locks::mutator_lock_) { - DCHECK(f->GetDeclaringClass()->IsInitialized()); + DCHECK(f->GetDeclaringClass()->IsInitializing()); MemberOffset offset(f->GetOffset()); const bool is_volatile = f->IsVolatile(); switch (field_type) { diff --git a/runtime/reflection.cc b/runtime/reflection.cc index 31329512b3..4700e3396a 100644 --- a/runtime/reflection.cc +++ b/runtime/reflection.cc @@ -776,7 +776,7 @@ void InvokeConstructor(const ScopedObjectAccessAlreadyRunnable& soa, CHECK(constructor->IsConstructor()); ObjPtr<mirror::Class> declaring_class = constructor->GetDeclaringClass(); - CHECK(declaring_class->IsInitialized()); + CHECK(declaring_class->IsInitializing()); // Calls to String.<init> should have been repplaced with with equivalent StringFactory calls. CHECK(!declaring_class->IsStringClass()); diff --git a/test/100-reflect2/src/Main.java b/test/100-reflect2/src/Main.java index 5f6ffa8ae9..56b4a82f84 100644 --- a/test/100-reflect2/src/Main.java +++ b/test/100-reflect2/src/Main.java @@ -308,11 +308,73 @@ class Main { } } + private static void testReflectFieldSetDuringClinit() { + try { + int value = ReflectFieldSetDuringClinit.intField; + int expected = 42; + if (value != expected) { + System.out.println("Unexpected value: " + value + ", expected: " + expected); + } + } catch (Exception e) { + // Error. + e.printStackTrace(System.out); + } + } + + private static void testReflectNewInstanceDuringClinit() { + try { + int value = ReflectNewInstanceDuringClinit.instance.intField; + int expected = 42; + if (value != expected) { + System.out.println("Unexpected value: " + value + ", expected: " + expected); + } + } catch (Exception e) { + // Error. + e.printStackTrace(System.out); + } + } + public static void main(String[] args) throws Exception { testFieldReflection(); testMethodReflection(); testConstructorReflection(); testPackagePrivateConstructor(); testPackagePrivateAccessibleConstructor(); + testReflectFieldSetDuringClinit(); + testReflectNewInstanceDuringClinit(); + } +} + +class ReflectFieldSetDuringClinit { + public static int intField; + + static { + try { + Field f = ReflectFieldSetDuringClinit.class.getDeclaredField("intField"); + f.setInt(null, 42); + } catch (Exception e) { + // Error. + e.printStackTrace(System.out); + } + } +} + +class ReflectNewInstanceDuringClinit { + public int intField; + + public ReflectNewInstanceDuringClinit() { + intField = 42; + } + + public static ReflectNewInstanceDuringClinit instance; + + static { + try { + Constructor<?> ctor = ReflectNewInstanceDuringClinit.class.getConstructor(); + instance = (ReflectNewInstanceDuringClinit) ctor.newInstance(); + } catch (Exception e) { + // Error. + e.printStackTrace(System.out); + } } } |