Bug 309440 - ArrayIndexOutOfBoundsException with parameter annotations
Summary: ArrayIndexOutOfBoundsException with parameter annotations
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.6.9   Edit
Hardware: PC Windows XP
: P2 major (vote)
Target Milestone: 1.6.9M2   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-04-16 05:26 EDT by Martin Schaffoener CLA
Modified: 2010-05-13 13:48 EDT (History)
1 user (show)

See Also:


Attachments
Crashing code with trigger script (24.75 KB, application/unknown)
2010-04-16 05:27 EDT, Martin Schaffoener CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Schaffoener CLA 2010-04-16 05:26:49 EDT
Build Identifier: 1.6.7a, 1.6.8

This is the followup bug to http://dev.eclipse.org/mhonarc/lists/aspectj-users/msg11911.html. Basically, the compiler crashes with an ArrayIndexOutOfBoundsException.

I'll attach a zip file with failing code, including a batch script to trigger the bug.


Reproducible: Always

Steps to Reproduce:
1. Unpack the zip file
2. Run the crashcompile.bat script
Comment 1 Martin Schaffoener CLA 2010-04-16 05:27:27 EDT
Created attachment 165070 [details]
Crashing code with trigger script
Comment 2 Andrew Clement CLA 2010-04-16 11:35:19 EDT
try specifying -1.5 instead of -1.6
Comment 3 Andrew Clement CLA 2010-04-16 12:04:33 EDT
I mentioned on the mailing list that I'd seen it around non-static inner types.  Another case of the same problem is with enums.  Basically anywhere that can cause extra (synthetic) method arguments to be added by the compiler can cause this kind of problem.

The problem is that the annotations that are recorded don't quite match the arguments.  In this case the problem is ExportMode, the enum.

The defined constructor is:

ExportMode(@Nonnull String aDisplayName)

the actual compiler generated constructor is:

foobar.ExportMode(java.lang.String, int, java.lang.String);
  RuntimeVisibleParameterAnnotations: length = 0x7
   01 00 01 00 22 00 00 

notice the single String argument has been prefixed by a name and id (for each enum value).  This creates a situation where the annotations (shown there, the 01 indicates there is 1 annotation) don't line up with the arguments.  That single annotation actually applies to the final String argument.

The compiler is expected to recognize this situation. 

The reason it makes a difference whether the source level specified is 1.5 or 1.6 is that for 1.5 annotations are ignored (they are not loaded by the compiler) - so it never gets it wrong.  When a 1.6 compiler level is specified the compiler loads the annotations as you might be doing some ast transformation work and want to see them.

As I expected, it is a bug in Eclipse 3.3 that is fixed in Eclipse 3.5 (possibly also in 3.4).  The solution is quite clear in the code BinaryTypeBinding.createMethod().

Here is the 3.3 code which computes whether to jump over synthetic arguments:

// Ignore synthetic argument for member types.
int startIndex = (method.isConstructor() && isMemberType() && !isStatic()) ? 1 : 0;

Here is the 3.5 code:

// Ignore synthetic argument for member types or enum types.
int startIndex = 0;
if (method.isConstructor()) {
	if (isMemberType() && !isStatic()) {
		// enclosing type
		startIndex++;
	}
	if (isEnum()) {
		// synthetic arguments (String, int)
		startIndex += 2;
	}
}

So we can see 3.3 does not consider the enum case and crashes due to not skipping the first two arguments.
Comment 4 Andrew Clement CLA 2010-04-16 18:22:07 EDT
I backported the fix from Eclipse 3.5.2 to the Eclipse 3.3 compiler that AspectJ uses (specifically 785_R33x).  Confirmed to fix this problem and allow usage of the -1.6 flag.
Comment 5 Martin Schaffoener CLA 2010-04-19 02:48:53 EDT
Do you want me to verify that the bug is fixed once a build containing the fix is available (and set the bug to VERIFIED)?
Comment 6 Andrew Clement CLA 2010-04-19 11:31:14 EDT
Hi Martin,

I don't require you to do that, but it is good to hear when users have confirmed the fixes are ok.  Your test program is now the basis of a regression test in AspectJ.  I wanted to get AspectJ 1.6.9m1 out before I fixed this because it involved rebuilding the jdt extensions to pick up the JDT fix.  Hopefully it will get into a built and an AJDT build this week.