diff options
| -rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 5 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 5 | ||||
| -rw-r--r-- | test/667-out-of-bounds/expected.txt | 1 | ||||
| -rw-r--r-- | test/667-out-of-bounds/info.txt | 3 | ||||
| -rw-r--r-- | test/667-out-of-bounds/src/Main.java | 30 |
5 files changed, 40 insertions, 4 deletions
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 39a07b82d1..828e7ffd1d 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -144,7 +144,8 @@ class BoundsCheckSlowPathX86 : public SlowPathCode { InvokeRuntimeCallingConvention calling_convention; if (array_length->IsArrayLength() && array_length->IsEmittedAtUseSite()) { // Load the array length into our temporary. - uint32_t len_offset = CodeGenerator::GetArrayLengthOffset(array_length->AsArrayLength()); + HArrayLength* length = array_length->AsArrayLength(); + uint32_t len_offset = CodeGenerator::GetArrayLengthOffset(length); Location array_loc = array_length->GetLocations()->InAt(0); Address array_len(array_loc.AsRegister<Register>(), len_offset); length_loc = Location::RegisterLocation(calling_convention.GetRegisterAt(1)); @@ -154,7 +155,7 @@ class BoundsCheckSlowPathX86 : public SlowPathCode { length_loc = Location::RegisterLocation(calling_convention.GetRegisterAt(2)); } __ movl(length_loc.AsRegister<Register>(), array_len); - if (mirror::kUseStringCompression) { + if (mirror::kUseStringCompression && length->IsStringLength()) { __ shrl(length_loc.AsRegister<Register>(), Immediate(1)); } } diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index c8032c25df..b07949fe97 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -195,7 +195,8 @@ class BoundsCheckSlowPathX86_64 : public SlowPathCode { InvokeRuntimeCallingConvention calling_convention; if (array_length->IsArrayLength() && array_length->IsEmittedAtUseSite()) { // Load the array length into our temporary. - uint32_t len_offset = CodeGenerator::GetArrayLengthOffset(array_length->AsArrayLength()); + HArrayLength* length = array_length->AsArrayLength(); + uint32_t len_offset = CodeGenerator::GetArrayLengthOffset(length->AsArrayLength()); Location array_loc = array_length->GetLocations()->InAt(0); Address array_len(array_loc.AsRegister<CpuRegister>(), len_offset); length_loc = Location::RegisterLocation(calling_convention.GetRegisterAt(1)); @@ -205,7 +206,7 @@ class BoundsCheckSlowPathX86_64 : public SlowPathCode { length_loc = Location::RegisterLocation(calling_convention.GetRegisterAt(2)); } __ movl(length_loc.AsRegister<CpuRegister>(), array_len); - if (mirror::kUseStringCompression) { + if (mirror::kUseStringCompression && length->IsStringLength()) { __ shrl(length_loc.AsRegister<CpuRegister>(), Immediate(1)); } } diff --git a/test/667-out-of-bounds/expected.txt b/test/667-out-of-bounds/expected.txt new file mode 100644 index 0000000000..e114c50371 --- /dev/null +++ b/test/667-out-of-bounds/expected.txt @@ -0,0 +1 @@ +java.lang.ArrayIndexOutOfBoundsException: length=5; index=82 diff --git a/test/667-out-of-bounds/info.txt b/test/667-out-of-bounds/info.txt new file mode 100644 index 0000000000..19be6950e2 --- /dev/null +++ b/test/667-out-of-bounds/info.txt @@ -0,0 +1,3 @@ +Regression test for the x86/x64 backends which under certain +cirumstances used to pass the wrong value for the length of +an array when throwing an AIOOBE. diff --git a/test/667-out-of-bounds/src/Main.java b/test/667-out-of-bounds/src/Main.java new file mode 100644 index 0000000000..7842569a6c --- /dev/null +++ b/test/667-out-of-bounds/src/Main.java @@ -0,0 +1,30 @@ +/* + * 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. + */ + +public class Main { + static int $noinline$arrayAccess(int[] array) { + return array[82]; + } + + public static void main(String[] args) { + int[] array = new int[5]; + try { + $noinline$arrayAccess(array); + } catch (Exception e) { + System.out.println(e); + } + } +} |