Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 290791

Summary: [compiler] Local final variable is uninitialized during the construction of the anonymous nested class instance.
Product: [Eclipse Project] JDT Reporter: topi.nieminen
Component: CoreAssignee: Olivier Thomann <Olivier_Thomann>
Status: CLOSED DUPLICATE QA Contact:
Severity: normal    
Priority: P3 CC: jarthana, Olivier_Thomann, philippe_mulet
Version: 3.5   
Target Milestone: 3.6 M3   
Hardware: PC   
OS: Windows Server 2003   
Whiteboard:
Attachments:
Description Flags
Reproduction none

Description topi.nieminen CLA 2009-09-29 05:34:13 EDT
User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Build Identifier: M20080221-1800

Source code example attached.

javac 1.6.0_05 compiled it correctly.

Reproducible: Always
Comment 1 topi.nieminen CLA 2009-09-29 05:35:09 EDT
Created attachment 148307 [details]
Reproduction
Comment 2 Jay Arthanareeswaran CLA 2009-09-29 06:30:25 EDT
This is no longer reproducible in 3.5 builds (I tried with 20090619-0625)
Comment 3 topi.nieminen CLA 2009-09-29 08:14:46 EDT
I upgraded to 20090920-1017, but it did not fix the problem.

But I also noticed that miscompilation only happens when
'Compiler compliance level' is set to 1.4.

Compliance level 1.5 works fine, but that can not be used in the project I'm working on.
Comment 4 Olivier Thomann CLA 2009-09-29 08:47:07 EDT
If you use javac 1.4, you will end up with the same problem.
So our behavior is consistent with javac.

> Compliance level 1.5 works fine, but that can not be used in the project I'm
> working on.
Why?
Nothing prevents you from setting the compliance to 1.5 and the target and source levels to 1.4.

I'll dig a bit more to explain why there is a difference between the two compliances 1.4 and 1.5.
Comment 5 Olivier Thomann CLA 2009-09-29 14:33:56 EDT
(In reply to comment #3)
> Compliance level 1.5 works fine, but that can not be used in the project I'm
> working on.
I don't understand how you can compile with javac 1.6, but you cannot use the compliance 1.5.
Comment 6 Olivier Thomann CLA 2009-09-29 14:48:35 EDT
The problem comes from the order of the calls inside the anonymous constructor:

In 1.5 or above:
  Sample$1(String arg0);
     0  aload_0 [this]
     1  aload_1 [arg0]
     2  putfield Sample$1.val$b : String [10]
     5  aload_0 [this]
     6  invokespecial Sample() [12]
     9  return

In 1.4 or above:
  Sample$1(String arg0);
     0  aload_0 [this]
     1  invokespecial Sample() [11]
     4  aload_0 [this]
     5  aload_1 [arg0]
     6  putfield Sample$1.val$b : String [14]
     9  return

So hook() is called once the field b is initialized with compliance 1.5 or above, but it is called before the field b is initialized with compliance 1.4.

In the compiler we are using the target platform value to know if we should generate the synthetic fields before or after the super call. We should change it to use the compliance level instead.
Comment 7 Olivier Thomann CLA 2009-09-29 15:15:13 EDT
The change that initialized synthetic fields before super call has been done to fix bug 23075.
In fact I was wrong. The current code is right. If you use javac with:
-target 1.3 and -source 1.3, you will see the same issue.

With compliance 1.4, the default target is below 1.4 and this explains why you see the issue with compliance 1.4.
Closing as a dup of bug 23075.

*** This bug has been marked as a duplicate of bug 23075 ***
Comment 8 topi.nieminen CLA 2009-09-30 04:02:39 EDT
(In reply to comment #5)
> (In reply to comment #3)
> > Compliance level 1.5 works fine, but that can not be used in the project I'm
> > working on.
> I don't understand how you can compile with javac 1.6, but you cannot use the
> compliance 1.5.

Yeah, you're right. Target level 1.4 is all that matters.
I assumed compiler compliance to 5.0 would imply target level >= 1.5 (and was wrong). 

I thought that defining source level 1.4 and target level 1.4 would define the behavior of the compiler entirely, and there would be nothing more for the compiler to be compliant with.
Comment 9 topi.nieminen CLA 2009-09-30 05:03:27 EDT
(In reply to comment #8)
> (In reply to comment #5)
> > (In reply to comment #3)
> > > Compliance level 1.5 works fine, but that can not be used in the project I'm
> > > working on.
> > I don't understand how you can compile with javac 1.6, but you cannot use the
> > compliance 1.5.
> 
> Yeah, you're right. Target level 1.4 is all that matters.
> I assumed compiler compliance to 5.0 would imply target level >= 1.5 (and was
> wrong). 
> 
> I thought that defining source level 1.4 and target level 1.4 would define the
> behavior of the compiler entirely, and there would be nothing more for the
> compiler to be compliant with.

.. and it there isn't. Target level 1.4 results in the correct compilation regardless of compiler compliance. Sorry about the noise.