Do not try to sharpen super calls to abstract methods.
Bug: 18380491
(cherry picked from commit 474123dccc5aa9a0dfe566d332174877fd5b7040)
Change-Id: I6637aaa562115f6b07d8637f0cc6658f1a6739bb
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index 1805d59..ebf7874 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -240,7 +240,8 @@
bool can_sharpen_super_based_on_type = (*invoke_type == kSuper) &&
(referrer_class != methods_class) && referrer_class->IsSubClass(methods_class) &&
resolved_method->GetMethodIndex() < methods_class->GetVTableLength() &&
- (methods_class->GetVTableEntry(resolved_method->GetMethodIndex()) == resolved_method);
+ (methods_class->GetVTableEntry(resolved_method->GetMethodIndex()) == resolved_method) &&
+ !resolved_method->IsAbstract();
if (can_sharpen_virtual_based_on_type || can_sharpen_super_based_on_type) {
// Sharpen a virtual call into a direct call. The method_idx is into referrer's
diff --git a/test/800-smali/expected.txt b/test/800-smali/expected.txt
index 1b813bf..01d7b81 100644
--- a/test/800-smali/expected.txt
+++ b/test/800-smali/expected.txt
@@ -3,4 +3,6 @@
FloatBadArgReg
negLong
sameFieldNames
+b/18380491
+invoke-super abstract
Done!
diff --git a/test/800-smali/smali/b_18380491AbstractBase.smali b/test/800-smali/smali/b_18380491AbstractBase.smali
new file mode 100644
index 0000000..7aa1b1a
--- /dev/null
+++ b/test/800-smali/smali/b_18380491AbstractBase.smali
@@ -0,0 +1,12 @@
+.class public LB18380491ActractBase;
+
+.super Ljava/lang/Object;
+
+.method public constructor <init>()V
+ .locals 0
+ invoke-direct {p0}, Ljava/lang/Object;-><init>()V
+ return-void
+.end method
+
+.method public abstract foo(I)I
+.end method
diff --git a/test/800-smali/smali/b_18380491ConcreteClass.smali b/test/800-smali/smali/b_18380491ConcreteClass.smali
new file mode 100644
index 0000000..db5ef3b
--- /dev/null
+++ b/test/800-smali/smali/b_18380491ConcreteClass.smali
@@ -0,0 +1,19 @@
+.class public LB18380491ConcreteClass;
+
+.super LB18380491ActractBase;
+
+.method public constructor <init>()V
+ .locals 0
+ invoke-direct {p0}, LB18380491ActractBase;-><init>()V
+ return-void
+.end method
+
+.method public foo(I)I
+ .locals 1
+ if-eqz p1, :invoke_super_abstract
+ return p1
+ :invoke_super_abstract
+ invoke-super {p0, p1}, LB18380491ActractBase;->foo(I)I
+ move-result v0
+ return v0
+.end method
diff --git a/test/800-smali/src/Main.java b/test/800-smali/src/Main.java
index 3a0f8ea..3f613ef 100644
--- a/test/800-smali/src/Main.java
+++ b/test/800-smali/src/Main.java
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.LinkedList;
@@ -55,6 +56,10 @@
new Object[]{100}, null, 100));
testCases.add(new TestCase("negLong", "negLong", "negLong", null, null, 122142L));
testCases.add(new TestCase("sameFieldNames", "sameFieldNames", "getInt", null, null, 7));
+ testCases.add(new TestCase("b/18380491", "B18380491ConcreteClass", "foo",
+ new Object[]{42}, null, 42));
+ testCases.add(new TestCase("invoke-super abstract", "B18380491ConcreteClass", "foo",
+ new Object[]{0}, new AbstractMethodError(), null));
}
public void runTests() {
@@ -116,6 +121,9 @@
} catch (Throwable exc) {
if (tc.expectedException == null) {
errorReturn = new IllegalStateException("Did not expect exception", exc);
+ } else if (exc instanceof InvocationTargetException && exc.getCause() != null &&
+ exc.getCause().getClass().equals(tc.expectedException.getClass())) {
+ // Expected exception is wrapped in InvocationTargetException.
} else if (!tc.expectedException.getClass().equals(exc.getClass())) {
errorReturn = new IllegalStateException("Expected " +
tc.expectedException.getClass().getName() +