diff options
| -rw-r--r-- | runtime/verifier/method_verifier.cc | 5 | ||||
| -rw-r--r-- | test/135-MirandaDispatch/expected.txt | 1 | ||||
| -rw-r--r-- | test/135-MirandaDispatch/smali/b_21646347.smali | 15 | ||||
| -rw-r--r-- | test/135-MirandaDispatch/src/Main.java | 9 |
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 = ®_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"); } } |