Bug 300133 - [1.5][compiler] Local classes inside enum constants generate default constructor without implicit constructor call
Summary: [1.5][compiler] Local classes inside enum constants generate default construc...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.6   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 3.6 M5   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-01-19 23:03 EST by Chris Jester-Young CLA
Modified: 2010-01-28 14:40 EST (History)
3 users (show)

See Also:
srikanth_sankaran: review+


Attachments
An example program that demonstrates the bug (1.00 KB, text/plain)
2010-01-19 23:04 EST, Chris Jester-Young CLA
no flags Details
Proposed fix + regression test (2.99 KB, patch)
2010-01-21 12:25 EST, Olivier Thomann CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Jester-Young CLA 2010-01-19 23:03:34 EST
Build Identifier: M20090917-0800

When you have an enum constant with a class body, and declare a local class within a method in the enum constant class body, Eclipse generates the default constructor for that local class without the required super() call. The verifier then rightly rejects that class.

See upcoming attached example.

Reproducible: Always

Steps to Reproduce:
1. Run the attached program in Eclipse, and watch it fail verification.
2. Compile the same program with Sun javac, and watch it run successfully.
Comment 1 Chris Jester-Young CLA 2010-01-19 23:04:53 EST
Created attachment 156594 [details]
An example program that demonstrates the bug
Comment 2 Olivier Thomann CLA 2010-01-21 10:28:02 EST
Reproduced:
Exception in thread "main" java.lang.VerifyError: (class: X$1$1Finder, method: <init> signature: (LX$1;Ljava/util/regex/Pattern;)V) Constructor must call super() or this()
        at X$1.createMatcher(X.java:22)
        at X.main(X.java:29)

Working on it.
Comment 3 Olivier Thomann CLA 2010-01-21 12:25:16 EST
Created attachment 156823 [details]
Proposed fix + regression test

This increased the nestedType counter to make sure that an implicit constructor call is inserted for the default constructor of the local class.
Comment 4 Olivier Thomann CLA 2010-01-21 12:25:37 EST
Srikanth, please review.
Comment 5 Olivier Thomann CLA 2010-01-21 22:35:15 EST
Released for 3.6M5.
Comment 6 Ayushman Jain CLA 2010-01-25 06:57:38 EST
Verified for 3.6M5 using build I20100122-0800
Comment 7 Srikanth Sankaran CLA 2010-01-25 06:59:50 EST
Verified.
Comment 8 Srikanth Sankaran CLA 2010-01-28 05:06:34 EST
Sorry it took me a long while to get to this and once
I got there a good while to understand the fix even
though the fix is only 4 lines long.

The fix looks OK, other than the nit that we needn't
have the statement 

this.variablesCounter[this.nestedType] = 0;
in Parser.consumeEnumConstantWithClassBody()

Are we sure the extra call to consumeNestedType won't cause any
issues ? Given

EnumConstant ::= EnumConstantHeader ForceNoDiet ClassBody RestoreDiet
ClassBody ::= '{' ClassBodyDeclarationsopt '}
ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
NestedType ::= $empty 
/.$putCase consumeNestedType(); $break./

So in any event there would have been a call to consumeNestedType.
It wouldn't have been in a convenient enough place to do a

    this.variablesCounter[this.nestedType]++;

though. I can't think of a problem with this, just that the counter
is holding an incorrect value.

I wonder if a more straightforward solution would have been possible
by checking whether we are dealing with a local anonymous type at
the call site of TypeDeclaration.createDefaultConstructor(boolean, boolean)
I didn't test this though -- Thanks.
Comment 9 Olivier Thomann CLA 2010-01-28 14:40:55 EST
You are right. The only thing I wanted to achieve was to make sure the variableCounter was incremented.
Feel free to revisit it.