OSDN Git Service

Fix a bug in reference type propagation.
authorNicolas Geoffray <ngeoffray@google.com>
Wed, 1 Jun 2016 15:30:20 +0000 (16:30 +0100)
committerNicolas Geoffray <ngeoffray@google.com>
Thu, 2 Jun 2016 10:12:46 +0000 (11:12 +0100)
The upper bound of a bound type is always exact, so we should
not use it for setting the type of the bound type.

bug:28730986
Change-Id: I214b8c3493838c22805555f88e8dc87cf9221376

compiler/optimizing/reference_type_propagation.cc
test/603-checker-instanceof/expected.txt [new file with mode: 0644]
test/603-checker-instanceof/info.txt [new file with mode: 0644]
test/603-checker-instanceof/src/Main.java [new file with mode: 0644]

index f2394f6..15f4928 100644 (file)
@@ -809,7 +809,11 @@ void ReferenceTypePropagation::UpdateBoundType(HBoundType* instr) {
   // Make sure that we don't go over the bounded type.
   ReferenceTypeInfo upper_bound_rti = instr->GetUpperBound();
   if (!upper_bound_rti.IsSupertypeOf(new_rti)) {
-    new_rti = upper_bound_rti;
+    // Note that the input might be exact, in which case we know the branch leading
+    // to the bound type is dead. We play it safe by not marking the bound type as
+    // exact.
+    bool is_exact = upper_bound_rti.GetTypeHandle()->CannotBeAssignedFromOtherTypes();
+    new_rti = ReferenceTypeInfo::Create(upper_bound_rti.GetTypeHandle(), is_exact);
   }
   instr->SetReferenceTypeInfo(new_rti);
 }
diff --git a/test/603-checker-instanceof/expected.txt b/test/603-checker-instanceof/expected.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/603-checker-instanceof/info.txt b/test/603-checker-instanceof/info.txt
new file mode 100644 (file)
index 0000000..5907abc
--- /dev/null
@@ -0,0 +1,2 @@
+Regression test for the compiler that used to wrongly optimize
+an instanceof.
diff --git a/test/603-checker-instanceof/src/Main.java b/test/603-checker-instanceof/src/Main.java
new file mode 100644 (file)
index 0000000..ddf4b92
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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 SuperClass {
+}
+
+class ChildClass extends SuperClass {
+}
+
+public class Main {
+
+  /// CHECK-START:    void Main.main(java.lang.String[]) builder (after)
+  /// CHECK:          BoundType  klass:SuperClass can_be_null:false exact:false
+
+  /// CHECK-START:    void Main.main(java.lang.String[]) builder (after)
+  /// CHECK-NOT:      BoundType  klass:SuperClass can_be_null:false exact:true
+  public static void main(String[] args) {
+    Object obj = new ChildClass();
+
+    // We need a fixed point iteration to hit the bogus type update
+    // of 'obj' below, so create a loop that updates the type of 'obj'.
+    for (int i = 1; i < 1; i++) {
+      obj = new Object();
+    }
+
+    if (obj instanceof SuperClass) {
+      // We used to wrongly type obj as an exact SuperClass from this point,
+      // meaning we were statically determining that the following instanceof
+      // would always fail.
+      if (!(obj instanceof ChildClass)) {
+        throw new Error("Expected a ChildClass, got " + obj.getClass());
+      }
+    }
+  }
+}