diff options
| -rw-r--r-- | test/664-aget-verifier/aget-verifier.cc | 41 | ||||
| -rw-r--r-- | test/664-aget-verifier/expected.txt | 2 | ||||
| -rw-r--r-- | test/664-aget-verifier/info.txt | 6 | ||||
| -rw-r--r-- | test/664-aget-verifier/src/Main.java | 49 | ||||
| -rw-r--r-- | test/Android.bp | 1 | ||||
| -rw-r--r-- | test/knownfailures.json | 5 |
6 files changed, 104 insertions, 0 deletions
diff --git a/test/664-aget-verifier/aget-verifier.cc b/test/664-aget-verifier/aget-verifier.cc new file mode 100644 index 0000000000..41372adf02 --- /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 0000000000..50e2e94985 --- /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 0000000000..b59cacb879 --- /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 0000000000..7a92b17a9d --- /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 fab664a3e2..7413ee50b3 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -411,6 +411,7 @@ cc_defaults { "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 e20c2c8ddd..20cfc34e43 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" } ] |