summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2019-08-02 13:59:27 +0100
committer Treehugger Robot <treehugger-gerrit@google.com> 2019-08-05 19:27:58 +0000
commit38a062eb7390f07ee0a318517f71d9b56491a5f7 (patch)
tree67204f1fbc785b888f9d5718e31cf22de6b2d727
parente80ecf31e0d58a90d6b2a1d65ec090c03abc86dc (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.cc2
-rw-r--r--runtime/reflection.cc2
-rw-r--r--test/100-reflect2/src/Main.java62
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);
+ }
}
}