Home | History | Annotate | Download | only in smali
      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