diff options
-rw-r--r-- | tests/bugs/DisjunctVarBinding.java | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/tests/bugs/DisjunctVarBinding.java b/tests/bugs/DisjunctVarBinding.java new file mode 100644 index 000000000..6d59f354f --- /dev/null +++ b/tests/bugs/DisjunctVarBinding.java @@ -0,0 +1,76 @@ +class A { + void m() { + System.out.println("A"); + } + } + +class B extends A { + void m() { + System.out.println("B"); + } + } + + +aspect IfPointcut { + + after(A a, B b) returning: + call(* foo(*,*)) && + (args(b,a) || args(a,b)) { + System.out.println("Woven"); + } +} + + +public class DisjunctVarBinding { + + public static void foo(A a, A b) { + a.m(); + b.m(); + } + + public static void main(String[] args) { + A a = new A(); + B b = new B(); + foo(b,a); + } + +} + +/* Example to illustrate a problem with variable + binding and (||) in pointcuts. When run, this program produces + java.lang.ClassCastException immediately after + the call to "foo". + + The reason is that the instance tests inherent + in the pointcut are done separately from the + variable binding. + + Decompiled, the code produced for the relevant call + to "foo" is as follows: + + -------------------------------------------------- + DisjunctVarBinding.foo(r5, r4); + label_0: + { + if (r5 instanceof B == false) + { + if (r4 instanceof B == false) + { + break label_0; + } + } + + IfPointcut.aspectOf().ajc$afterReturning$IfPointcut$26d(r5, (B) r4); + } + -------------------------------------------------- + It should however read something like this, using the instance + tests to determine the appropriate variable binding + + -------------------------------------------------- + DisjunctVarBinding.foo(r5,r4); + if (r4 instanceof B) + IfPointcut.aspectOf().ajc$afterReturning$IfPointcut$26d(r5, (B)r4) + else if (r5 instanceof A) + IfPointcut.aspectOf().ajc$afterReturning$IfPointcut$26d(r4,(B)r5) + -------------------------------------------------- +*/
\ No newline at end of file |