Bug 40109 - switch statement in aspects crashes weaving
Summary: switch statement in aspects crashes weaving
Status: RESOLVED DUPLICATE of bug 39479
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: ---   Edit
Assignee: Jim Hugunin CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-07-15 10:29 EDT by Charles Zhang CLA
Modified: 2003-07-16 19:28 EDT (History)
0 users

See Also:


Attachments
Test case (444 bytes, text/plain)
2003-07-15 10:33 EDT, Charles Zhang CLA
no flags Details
Patch for LazyMethodGen to fix this bug. (1.70 KB, patch)
2003-07-15 12:33 EDT, Andrew Clement CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Charles Zhang CLA 2003-07-15 10:29:17 EDT
Adding a switch statement in the aspect code causes the weaving process to 
throw java.lang.NullPointer. This error is reproducable on ajc1.1.0, the 
formal release version. ajc1.0, however, works fine. 

To re-produce, use the following java program:

public class Test {
	public String method1(){
		System.out.println("method1");
		return "method1";
	}
        
        public static void  main(String [] args)
	{
		System.out.println(new Test().method1());
	}
}

And the following AspectJ code:

public privileged aspect TestAspect {
	String around(Test t):target(t)&&
	call(public String method1())
	{
		int flag = 1;
		switch(flag)
		{
			case 1: 
		}
		return null;
	}
}

Here is the output I got:
trouble in:
public class Test extends java.lang.Object:
  public void <init>():
                    ALOAD_0     // Test this   (line 13)
                    INVOKESPECIAL java.lang.Object.<init> ()V
    constructor-execution(void Test.<init>())
    |               RETURN
    constructor-execution(void Test.<init>())
  end public void <init>()

  public String method1():
    method-execution(java.lang.String Test.method1())
    | field-get(java.io.PrintStream java.lang.System.out)
    | |             GETSTATIC java.lang.System.out Ljava/io/PrintStream;   
(line 15)
    | field-get(java.io.PrintStream java.lang.System.out)
    |               LDC "method1"
    | method-call(void java.io.PrintStream.println(java.lang.String))
    | |             INVOKEVIRTUAL java.io.PrintStream.println 
(Ljava/lang/String;)V
    | method-call(void java.io.PrintStream.println(java.lang.String))
    |               LDC "method1"   (line 16)
    |               ARETURN
    method-execution(java.lang.String Test.method1())
  end public String method1()

  public static void main(String[]):
    method-execution(void Test.main(java.lang.String[]))
    | field-get(java.io.PrintStream java.lang.System.out)
    | |             GETSTATIC java.lang.System.out Ljava/io/PrintStream;   
(line 23)
    | field-get(java.io.PrintStream java.lang.System.out)
    |               NEW Test
    |               DUP
    | constructor-call(void Test.<init>())
    | |             INVOKESPECIAL Test.<init> ()V
    | constructor-call(void Test.<init>())
    |               ASTORE_1
    | method-call(java.lang.String Test.method1())
    | |             ALOAD_1
    | |             INVOKESTATIC Test1Aspect.aspectOf ()LTest1Aspect;
    | |             ALOAD_1
    | |             ACONST_NULL
    | |             INVOKESTATIC Test.method1_aroundBody1$advice 
(LTest;LTest1Aspect;LTest;Lorg/aspectj/runtime/internal
/AroundClosure;)Ljava/lang/String;
    | method-call(java.lang.String Test.method1())
    | method-call(void java.io.PrintStream.println(java.lang.String))
    | |             INVOKEVIRTUAL java.io.PrintStream.println 
(Ljava/lang/String;)V
    | method-call(void java.io.PrintStream.println(java.lang.String))
    |               RETURN   (line 24)
    method-execution(void Test.main(java.lang.String[]))
  end public static void main(String[])

  static final String method1_aroundBody0(Test):
                    ALOAD_0
                    INVOKEVIRTUAL Test.method1 ()Ljava/lang/String;   (line 23)
                    ARETURN
  end static final String method1_aroundBody0(Test)

  static final String method1_aroundBody1$advice(Test, Test1Aspect, Test, 
org.aspectj.runtime.internal.AroundClosure):
    advice-execution(java.lang.String Test1Aspect.ajc$around$Test1Aspect$e7
(Test, org.aspectj.runtime.internal.AroundClo
sure))
    |               ICONST_1   (line 18)
    |               ISTORE 4
    |               ILOAD 4   (line 19)
    |               TABLESWITCH
    |                 1:        null
    |                 default:  L0
    |           L0: ACONST_NULL   (line 23)
    |               ARETURN
    advice-execution(java.lang.String Test1Aspect.ajc$around$Test1Aspect$e7
(Test, org.aspectj.runtime.internal.AroundClo
sure))
  end static final String method1_aroundBody1$advice(Test, Test1Aspect, Test, 
org.aspectj.runtime.internal.AroundClosure
)
end public class Test
ABORT
Exception thrown from AspectJ 1.1.0

This might be logged as a bug already -- find current bugs at
  http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Compiler

Bugs for exceptions thrown have titles File:line from the top stack,
e.g., "SomeFile.java:243"

If you don't find the exception below in a bug, please add a new bug
at http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AspectJ
To make the bug a priority, please include a test program
that can reproduce this exception.
null
java.lang.NullPointerException
        at org.aspectj.weaver.bcel.LazyMethodGen.remap(LazyMethodGen.java:892)
        at org.aspectj.weaver.bcel.LazyMethodGen.packBody
(LazyMethodGen.java:800)
        at org.aspectj.weaver.bcel.LazyMethodGen.pack(LazyMethodGen.java:706)
        at org.aspectj.weaver.bcel.LazyMethodGen.getMethod
(LazyMethodGen.java:284)
        at org.aspectj.weaver.bcel.LazyClassGen.writeBack
(LazyClassGen.java:164)
        at org.aspectj.weaver.bcel.LazyClassGen.getJavaClass
(LazyClassGen.java:169)
        at org.aspectj.weaver.bcel.BcelWeaver.dump(BcelWeaver.java:417)
        at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:364)
        at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:335)
        at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:272)
        at 
org.aspectj.ajdt.internal.core.builder.AjBuildManager.weaveAndGenerateClassFile
s(AjBuildManager.java:256)
        at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild
(AjBuildManager.java:164)
        at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild
(AjBuildManager.java:78)
        at org.aspectj.ajdt.ajc.AjdtCommand.doCommand(AjdtCommand.java:106)
        at org.aspectj.ajdt.ajc.AjdtCommand.runCommand(AjdtCommand.java:60)
        at org.aspectj.tools.ajc.Main.run(Main.java:217)
        at org.aspectj.tools.ajc.Main.runMain(Main.java:155)
        at org.aspectj.tools.ajc.Main.main(Main.java:72)


1 fail|abort
Comment 1 Charles Zhang CLA 2003-07-15 10:33:30 EDT
Created attachment 5464 [details]
Test case
Comment 2 Andrew Clement CLA 2003-07-15 12:33:32 EDT
Created attachment 5465 [details]
Patch for LazyMethodGen to fix this bug.

The above patch does the same kind of fix as in 39479 - when a bcel instruction
is copied, it checks to see if it is a Select - if it is then it does a special
kind of copy.  This works around a BCEL bug - see 39479 for more discussion.
Comment 3 Jim Hugunin CLA 2003-07-16 19:28:04 EDT
The general fix for bug #39479 fixes this bug as well, so its being marked as
a duplicate.  This bug report was very valuable in identifying the need for
a properly general solution to that bug.

*** This bug has been marked as a duplicate of 39479 ***