summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/verifier/method_verifier.cc5
-rw-r--r--test/135-MirandaDispatch/expected.txt1
-rw-r--r--test/135-MirandaDispatch/smali/b_21646347.smali15
-rw-r--r--test/135-MirandaDispatch/src/Main.java9
4 files changed, 29 insertions, 1 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 9faaa4a57e..4d88227956 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -3318,7 +3318,10 @@ ArtMethod* MethodVerifier::VerifyInvocationArgsFromIterator(
}
if (method_type != METHOD_INTERFACE && !actual_arg_type.IsZero()) {
const RegType* res_method_class;
- if (res_method != nullptr) {
+ // Miranda methods have the declaring interface as their declaring class, not the abstract
+ // class. It would be wrong to use this for the type check (interface type checks are
+ // postponed to runtime).
+ if (res_method != nullptr && !res_method->IsMiranda()) {
mirror::Class* klass = res_method->GetDeclaringClass();
std::string temp;
res_method_class = &reg_types_.FromClass(klass->GetDescriptor(&temp), klass,
diff --git a/test/135-MirandaDispatch/expected.txt b/test/135-MirandaDispatch/expected.txt
index 134d8d0b47..5b098e5fac 100644
--- a/test/135-MirandaDispatch/expected.txt
+++ b/test/135-MirandaDispatch/expected.txt
@@ -1 +1,2 @@
+b/21646347
Finishing
diff --git a/test/135-MirandaDispatch/smali/b_21646347.smali b/test/135-MirandaDispatch/smali/b_21646347.smali
new file mode 100644
index 0000000000..b4979a5357
--- /dev/null
+++ b/test/135-MirandaDispatch/smali/b_21646347.smali
@@ -0,0 +1,15 @@
+.class public LB21646347;
+
+# If an invoke-virtual dispatches to a miranda method, ensure that we test for the receiver
+# being a subclass of the abstract class, not postpone the check because the miranda method's
+# declaring class is an interface.
+
+.super Ljava/lang/Object;
+
+.method public static run(LB21646347;)V
+ .registers 1
+ # Invoke the miranda method on an object of this class. This should fail type-checking,
+ # instead of letting this pass as the declaring class is an interface.
+ invoke-virtual {v0}, LMain$AbstractClass;->m()V
+ return-void
+.end method
diff --git a/test/135-MirandaDispatch/src/Main.java b/test/135-MirandaDispatch/src/Main.java
index bb005b0103..ada8cefead 100644
--- a/test/135-MirandaDispatch/src/Main.java
+++ b/test/135-MirandaDispatch/src/Main.java
@@ -46,6 +46,15 @@ public class Main {
if (counter != loopIterations * loopIterations) {
System.out.println("Expected " + loopIterations * loopIterations + " got " + counter);
}
+
+ try {
+ Class<?> b21646347 = Class.forName("B21646347");
+ throw new RuntimeException("Expected a VerifyError");
+ } catch (VerifyError expected) {
+ System.out.println("b/21646347");
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
System.out.println("Finishing");
}
}