Do not place null check on unresolved method calls.
Rationale:
These invokes drop through the runtime anyway where various
checks are done, including null check. A few of these
checks need to occur before the null check.
With fail-before/pass-after smali test.
BUG=29068831
Change-Id: I260715e742365433a323598d97f7fdab321e8512
diff --git a/test/529-checker-unresolved/src/Main.java b/test/529-checker-unresolved/src/Main.java
index a934377..5a36ba5 100644
--- a/test/529-checker-unresolved/src/Main.java
+++ b/test/529-checker-unresolved/src/Main.java
@@ -114,19 +114,31 @@
expectEquals(o, c.instanceObject);
}
+ /// CHECK-START: void Main.callUnresolvedNull(UnresolvedClass) register (before)
+ /// CHECK-NOT: NullCheck
static public void callUnresolvedNull(UnresolvedClass c) {
int x = 0;
try {
x = c.instanceInt;
throw new Error("Expected NPE");
} catch (NullPointerException e) {
+ x -= 1;
}
- expectEquals(0, x);
+ expectEquals(-1, x);
try {
c.instanceInt = -1;
throw new Error("Expected NPE");
} catch (NullPointerException e) {
+ x -= 1;
}
+ expectEquals(-2, x);
+ try {
+ c.virtualMethod();
+ throw new Error("Expected NPE");
+ } catch (NullPointerException e) {
+ x -= 1;
+ }
+ expectEquals(-3, x);
}
static public void testInstanceOf(Object o) {
diff --git a/test/600-verifier-fails/expected.txt b/test/600-verifier-fails/expected.txt
index 8399969..eaa0c93 100644
--- a/test/600-verifier-fails/expected.txt
+++ b/test/600-verifier-fails/expected.txt
@@ -2,3 +2,4 @@
passed B
passed C
passed D
+passed E
diff --git a/test/600-verifier-fails/info.txt b/test/600-verifier-fails/info.txt
index f77de05..df2396e 100644
--- a/test/600-verifier-fails/info.txt
+++ b/test/600-verifier-fails/info.txt
@@ -10,9 +10,11 @@
bail immediately and not allow soft verification failures to pile up
behind it to avoid fatal message later on
(C) b/29068831:
- access validation should occur prior to null reference check
+ access validation on field should occur prior to null reference check
(D) b/29126870:
soft verification failure (cannot access) should not hide the hard
verification failure (non-reference type) to avoid a compiler crash
later on
+(E) b/29068831:
+ access validation on method should occur prior to null reference check
diff --git a/test/600-verifier-fails/smali/invoke.smali b/test/600-verifier-fails/smali/invoke.smali
new file mode 100644
index 0000000..616d63c
--- /dev/null
+++ b/test/600-verifier-fails/smali/invoke.smali
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2016 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.
+
+.class public LE;
+.super Ljava/lang/Object;
+
+.method public constructor <init>()V
+ .registers 2
+ invoke-direct {v1}, Ljava/lang/Object;-><init>()V
+ const v0, 0
+ invoke-virtual {v0}, LMain;->privateMethod()V
+ return-void
+.end method
diff --git a/test/600-verifier-fails/src/Main.java b/test/600-verifier-fails/src/Main.java
index a6a07fd..fa25d58 100644
--- a/test/600-verifier-fails/src/Main.java
+++ b/test/600-verifier-fails/src/Main.java
@@ -22,6 +22,8 @@
private int privateField = 0;
+ private void privateMethod() { }
+
private static void test(String name) throws Exception {
try {
Class<?> a = Class.forName(name);
@@ -36,5 +38,6 @@
test("B");
test("C");
test("D");
+ test("E");
}
}