Add test where aget on potential null array fails verification.
Bug: 64683522
Test: mm test-art-host-run-test
Change-Id: Idaaf87c3848873a39c75ce4b9cd0fc57620c4972
diff --git a/test/664-aget-verifier/aget-verifier.cc b/test/664-aget-verifier/aget-verifier.cc
new file mode 100644
index 0000000..41372ad
--- /dev/null
+++ b/test/664-aget-verifier/aget-verifier.cc
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "dex_file.h"
+
+#include "art_method-inl.h"
+#include "jni.h"
+#include "method_reference.h"
+#include "mirror/class-inl.h"
+#include "mirror/executable.h"
+#include "scoped_thread_state_change-inl.h"
+#include "thread.h"
+
+namespace art {
+namespace {
+
+extern "C" JNIEXPORT jboolean JNICALL Java_Main_testCompiled(JNIEnv* env,
+ jclass,
+ jobject method) {
+ CHECK(method != nullptr);
+ ScopedObjectAccess soa(env);
+ ObjPtr<mirror::Executable> exec = soa.Decode<mirror::Executable>(method);
+ ArtMethod* art_method = exec->GetArtMethod();
+ return art_method->HasAnyCompiledCode();
+}
+
+} // namespace
+} // namespace art
diff --git a/test/664-aget-verifier/expected.txt b/test/664-aget-verifier/expected.txt
new file mode 100644
index 0000000..50e2e94
--- /dev/null
+++ b/test/664-aget-verifier/expected.txt
@@ -0,0 +1,2 @@
+JNI_OnLoad called
+test method successfully verified/compiled.
diff --git a/test/664-aget-verifier/info.txt b/test/664-aget-verifier/info.txt
new file mode 100644
index 0000000..b59cacb
--- /dev/null
+++ b/test/664-aget-verifier/info.txt
@@ -0,0 +1,6 @@
+Tests how the verifier handles aget on an array that was initially null.
+
+The verifier will flag aget instructions as have_pending_runtime_throw_failure_
+if the array register is potentially null, even if the aget is guarded by null
+checks and never actually null at runtime. This fails compile-time verification,
+preventing otherwise good method from being compiled.
diff --git a/test/664-aget-verifier/src/Main.java b/test/664-aget-verifier/src/Main.java
new file mode 100644
index 0000000..7a92b17
--- /dev/null
+++ b/test/664-aget-verifier/src/Main.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+import java.lang.reflect.Method;
+
+public class Main {
+
+ public static void main(String[] args) {
+ System.loadLibrary(args[0]);
+
+ test();
+
+ try {
+ if (testCompiled(Main.class.getDeclaredMethod("test"))) {
+ System.out.println("test method successfully verified/compiled.");
+ } else {
+ System.out.println("test method failed to verify/compile.");
+ }
+ } catch (Exception e) {
+ System.out.println("Got unexpected exception: " + e);
+ }
+ }
+
+ public static void test() {
+ int[] maybe_null_array = null;
+ for (int i = 0; i < 2; i++) {
+ int[] non_null_array = new int[1];
+ if (maybe_null_array != null) {
+ i = maybe_null_array[0] + 1;
+ }
+ maybe_null_array = non_null_array;
+ }
+ }
+
+ public static native boolean testCompiled(Method method);
+}
diff --git a/test/Android.bp b/test/Android.bp
index fab664a..7413ee5 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -411,6 +411,7 @@
"642-fp-callees/fp_callees.cc",
"647-jni-get-field-id/get_field_id.cc",
"656-annotation-lookup-generic-jni/test.cc",
+ "664-aget-verifier/aget-verifier.cc",
"708-jit-cache-churn/jit.cc"
],
shared_libs: [
diff --git a/test/knownfailures.json b/test/knownfailures.json
index e20c2c8..20cfc34 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -714,5 +714,10 @@
"968-default-partial-compile-gen"],
"env_vars": {"SANITIZE_HOST": "address"},
"description": ["Test hits dex2oat watchdog timeout (60sec) on art-asan"]
+ },
+ {
+ "tests": "664-aget-verifier",
+ "description": ["Aget on potentially null array fails verification."],
+ "bug": "b/64683522"
}
]