diff options
| -rw-r--r-- | compiler/optimizing/instruction_builder.cc | 15 | ||||
| -rw-r--r-- | compiler/optimizing/instruction_builder.h | 3 | ||||
| -rw-r--r-- | test/529-checker-unresolved/src/Main.java | 14 | ||||
| -rw-r--r-- | test/600-verifier-fails/expected.txt | 1 | ||||
| -rw-r--r-- | test/600-verifier-fails/info.txt | 4 | ||||
| -rw-r--r-- | test/600-verifier-fails/smali/invoke.smali | 25 | ||||
| -rw-r--r-- | test/600-verifier-fails/src/Main.java | 3 |
7 files changed, 57 insertions, 8 deletions
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 135038b753..f2286e46e6 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -833,7 +833,8 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction, register_index, is_range, descriptor, - nullptr /* clinit_check */); + nullptr, /* clinit_check */ + true /* is_unresolved */); } // Potential class initialization check, in the case of a static method call. @@ -898,7 +899,8 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction, register_index, is_range, descriptor, - clinit_check); + clinit_check, + false /* is_unresolved */); } bool HInstructionBuilder::BuildNewInstance(uint16_t type_index, uint32_t dex_pc) { @@ -1091,14 +1093,17 @@ bool HInstructionBuilder::HandleInvoke(HInvoke* invoke, uint32_t register_index, bool is_range, const char* descriptor, - HClinitCheck* clinit_check) { + HClinitCheck* clinit_check, + bool is_unresolved) { DCHECK(!invoke->IsInvokeStaticOrDirect() || !invoke->AsInvokeStaticOrDirect()->IsStringInit()); size_t start_index = 0; size_t argument_index = 0; if (invoke->GetOriginalInvokeType() != InvokeType::kStatic) { // Instance call. - HInstruction* arg = LoadNullCheckedLocal(is_range ? register_index : args[0], - invoke->GetDexPc()); + uint32_t obj_reg = is_range ? register_index : args[0]; + HInstruction* arg = is_unresolved + ? LoadLocal(obj_reg, Primitive::kPrimNot) + : LoadNullCheckedLocal(obj_reg, invoke->GetDexPc()); invoke->SetArgumentAt(0, arg); start_index = 1; argument_index = 1; diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h index 0e3e5a7c34..9cfc065da6 100644 --- a/compiler/optimizing/instruction_builder.h +++ b/compiler/optimizing/instruction_builder.h @@ -237,7 +237,8 @@ class HInstructionBuilder : public ValueObject { uint32_t register_index, bool is_range, const char* descriptor, - HClinitCheck* clinit_check); + HClinitCheck* clinit_check, + bool is_unresolved); bool HandleStringInit(HInvoke* invoke, uint32_t number_of_vreg_arguments, diff --git a/test/529-checker-unresolved/src/Main.java b/test/529-checker-unresolved/src/Main.java index a934377ddf..5a36ba5d9c 100644 --- a/test/529-checker-unresolved/src/Main.java +++ b/test/529-checker-unresolved/src/Main.java @@ -114,19 +114,31 @@ public class Main extends UnresolvedSuperClass { 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 8399969a2d..eaa0c933c4 100644 --- a/test/600-verifier-fails/expected.txt +++ b/test/600-verifier-fails/expected.txt @@ -2,3 +2,4 @@ passed A 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 f77de05ac7..df2396eef7 100644 --- a/test/600-verifier-fails/info.txt +++ b/test/600-verifier-fails/info.txt @@ -10,9 +10,11 @@ dexfuzz on the DEX files of fuzzingly random generated Java test. 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 0000000000..616d63c479 --- /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 a6a07fda79..fa25d58e43 100644 --- a/test/600-verifier-fails/src/Main.java +++ b/test/600-verifier-fails/src/Main.java @@ -22,6 +22,8 @@ public class Main { 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 @@ public class Main { test("B"); test("C"); test("D"); + test("E"); } } |