1# Test that the verifier does not stash methods incorrectly because they are being invoked with
2# the wrong opcode.
3#
4# When using invoke-interface on a method id that is not from an interface class, we should throw
5# an IncompatibleClassChangeError. FindInterfaceMethod assumes that the given type is an interface,
6# so we can construct a class hierarchy that would have a surprising result:
7#
8#   interface I {
9#     void a();
10#   }
11#
12#   class B implements I {
13#      // miranda method for a, or a implemented.
14#   }
15#
16#   class C extends B {
17#   }
18#
19# Then calling invoke-interface C.a() will go wrong if there is no explicit check: a can't be found
20# in C, but in the interface table, so we will find an interface method and pass ICCE checks.
21#
22# If we do this before a correct invoke-virtual C.a(), we poison the dex cache with an incorrect
23# method. In this test, this is done in A (A < B, so processed first). The "real" call is in B.
24
25.class public LB21869691A;
26
27.super Ljava/lang/Object;
28
29.method public constructor <init>()V
30    .registers 1
31    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
32    return-void
33.end method
34
35.method public run()V
36  .registers 3
37  new-instance v0, LB21869691C;
38  invoke-direct {v0}, LB21869691C;-><init>()V
39  invoke-virtual {v2, v0}, LB21869691A;->callinf(LB21869691C;)V
40  return-void
41.end method
42
43.method public callinf(LB21869691C;)V
44  .registers 2
45  invoke-interface {p1}, LB21869691C;->a()V
46  return-void
47.end method
48