OSDN Git Service

Quick: Fix range check for intrinsic String.charAt() on x86.
authorVladimir Marko <vmarko@google.com>
Mon, 26 Jan 2015 14:06:46 +0000 (14:06 +0000)
committerVladimir Marko <vmarko@google.com>
Mon, 26 Jan 2015 16:29:59 +0000 (16:29 +0000)
Bug: 19125146

(cherry picked from commit 00ca84730a21578dcc6b47bd8e08b78ab9b2dded)

Change-Id: I67184371597fdcc9d9186172c1cff4efd3ca3093

compiler/dex/quick/x86/target_x86.cc
test/082-inline-execute/src/Main.java

index 0f48d26..873db7e 100755 (executable)
@@ -2854,7 +2854,7 @@ bool X86Mir2Lir::GenInlinedCharAt(CallInfo* info) {
     if (rl_idx.is_const) {
       LIR* comparison;
       range_check_branch = OpCmpMemImmBranch(
-          kCondUlt, RegStorage::InvalidReg(), rl_obj.reg, count_offset,
+          kCondLs, RegStorage::InvalidReg(), rl_obj.reg, count_offset,
           mir_graph_->ConstantValue(rl_idx.orig_sreg), nullptr, &comparison);
       MarkPossibleNullPointerExceptionAfter(0, comparison);
     } else {
index 56972ff..84405cc 100644 (file)
@@ -125,7 +125,11 @@ public class Main {
     Assert.assertEquals('N', testStr.charAt(0));
     Assert.assertEquals('o', testStr.charAt(1));
     Assert.assertEquals(' ', testStr.charAt(10));
-    Assert.assertEquals('e', testStr.charAt(testStr.length()-1));
+    Assert.assertEquals('e', testStr.charAt(14));  // 14 = testStr.length()-1 as a constant.
+    Assert.assertEquals('N', test_String_charAt_inner(testStr, 0));
+    Assert.assertEquals('o', test_String_charAt_inner(testStr, 1));
+    Assert.assertEquals(' ', test_String_charAt_inner(testStr, 10));
+    Assert.assertEquals('e', test_String_charAt_inner(testStr, testStr.length()-1));
 
     try {
       testStr.charAt(-1);
@@ -137,6 +141,33 @@ public class Main {
       Assert.fail();
     } catch (StringIndexOutOfBoundsException expected) {
     }
+    try {
+      testStr.charAt(15);  // 15 = "Now is the time".length()
+      Assert.fail();
+    } catch (StringIndexOutOfBoundsException expected) {
+    }
+    try {
+      test_String_charAt_inner(testStr, -1);
+      Assert.fail();
+    } catch (StringIndexOutOfBoundsException expected) {
+    }
+    try {
+      test_String_charAt_inner(testStr, 80);
+      Assert.fail();
+    } catch (StringIndexOutOfBoundsException expected) {
+    }
+    try {
+      test_String_charAt_inner(testStr, 15);  // 15 = "Now is the time".length()
+      Assert.fail();
+    } catch (StringIndexOutOfBoundsException expected) {
+    }
+
+    String strEmpty = "";
+    try {
+      strEmpty.charAt(0);
+      Assert.fail();
+    } catch (StringIndexOutOfBoundsException expected) {
+    }
 
     String strNull = null;
     try {
@@ -146,6 +177,11 @@ public class Main {
     }
   }
 
+  private static char test_String_charAt_inner(String s, int index) {
+    // Using non-constant index here (assuming that this method wasn't inlined).
+    return s.charAt(index);
+  }
+
   static int start;
   private static int[] negIndex = { -100000 };
   public static void test_String_indexOf() {