Bug 324848 - [1.6][compiler] NullPointerException when trying to synchronize on non-existing outer class instance
Summary: [1.6][compiler] NullPointerException when trying to synchronize on non-existi...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.7   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: 3.7 M2   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-09-09 09:45 EDT by Heiko Böttger CLA
Modified: 2010-09-16 02:38 EDT (History)
3 users (show)

See Also:
srikanth_sankaran: review+


Attachments
Proposed fix + regression tests (98.18 KB, patch)
2010-09-10 15:08 EDT, Olivier Thomann CLA
no flags Details | Diff
Proposed fix + regression tests (55.78 KB, patch)
2010-09-10 15:23 EDT, 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 Heiko Böttger CLA 2010-09-09 09:45:15 EDT
Build Identifier: 20100617-1415

I got the following NullPointerExpception when trying to synchronize on the instance of an outer class inside an anonymous inner-class that was created in side a static method:

java.lang.NullPointerException
	at org.eclipse.jdt.internal.compiler.ClassFile.traverse(ClassFile.java:7655)
	at org.eclipse.jdt.internal.compiler.ClassFile.completeCodeAttribute(ClassFile.java:1621)
	at org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.generateCode(AbstractMethodDeclaration.java:245)
	at org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.generateCode(AbstractMethodDeclaration.java:179)
	at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCode(TypeDeclaration.java:542)
	at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCode(TypeDeclaration.java:585)
	at org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression.generateCode(QualifiedAllocationExpression.java:173)
	at org.eclipse.jdt.internal.compiler.ast.Expression.generateCode(Expression.java:601)
	at org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.generateCode(AbstractMethodDeclaration.java:232)
	at org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.generateCode(AbstractMethodDeclaration.java:179)
	at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCode(TypeDeclaration.java:542)
	at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCode(TypeDeclaration.java:611)
	at org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.generateCode(CompilationUnitDeclaration.java:361)
	at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(CompilationUnitResolver.java:1187)
	at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(CompilationUnitResolver.java:681)
	at org.eclipse.jdt.core.dom.ASTParser.internalCreateAST(ASTParser.java:1175)
	at org.eclipse.jdt.core.dom.ASTParser.createAST(ASTParser.java:801)
	at org.eclipse.jdt.internal.ui.javaeditor.ASTProvider$1.run(ASTProvider.java:543)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.jdt.internal.ui.javaeditor.ASTProvider.createAST(ASTProvider.java:536)
	at org.eclipse.jdt.internal.ui.javaeditor.ASTProvider.getAST(ASTProvider.java:479)
	at org.eclipse.jdt.ui.SharedASTProvider.getAST(SharedASTProvider.java:126)
	at org.eclipse.jdt.ui.OverrideIndicatorLabelDecorator.getOverrideIndicators(OverrideIndicatorLabelDecorator.java:161)
	at org.eclipse.jdt.ui.OverrideIndicatorLabelDecorator.computeAdornmentFlags(OverrideIndicatorLabelDecorator.java:136)
	at org.eclipse.jdt.ui.OverrideIndicatorLabelDecorator.decorate(OverrideIndicatorLabelDecorator.java:273)
	at org.eclipse.ui.internal.decorators.LightweightDecoratorDefinition.decorate(LightweightDecoratorDefinition.java:269)
	at org.eclipse.ui.internal.decorators.LightweightDecoratorManager$LightweightRunnable.run(LightweightDecoratorManager.java:81)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.ui.internal.decorators.LightweightDecoratorManager.decorate(LightweightDecoratorManager.java:365)
	at org.eclipse.ui.internal.decorators.LightweightDecoratorManager.getDecorations(LightweightDecoratorManager.java:347)
	at 
org.eclipse.ui.internal.decorators.DecorationScheduler$1.ensureResultCached(DecorationScheduler.java:371)
	at org.eclipse.ui.internal.decorators.DecorationScheduler$1.run(DecorationScheduler.java:331)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)


Reproducible: Always

Steps to Reproduce:
1. create a new java class ("Test")
2. create a static method ("main")
3. create a local final variable ("final boolean x = true");
4. create a new anonymous or named innerclass ("new Runnable(){}")
5. create a method ("run")
6. add a synchronize-block and synchronize on the instanceof the outer class ("synchronize (Test.this) {}")
7. access the final variable inside the synchronized block ("System.out.println(x);")

Complete file:

package ch.actifsource.test;

public class Test {
  
  public static void test()  {
    final boolean x = true;
    new Runnable() {
      
      @Override
      public void run() {
        synchronized (Test.this) {
          System.out.println(x);
        }
      }
    };
  }
}
Comment 1 Olivier Thomann CLA 2010-09-10 09:16:57 EDT
Reproduced.
Working on it.
Comment 2 Olivier Thomann CLA 2010-09-10 09:21:46 EDT
The problem occurs only in 1.6 mode. In 1.5, the compiler error is properly reported and the compilation aborted.
Comment 3 Olivier Thomann CLA 2010-09-10 09:38:17 EDT
The problem comes from that we tag the outer most method when the problem is detected, but we check the current method (field ignoreFurtherInvestigation) to find out if we should stop the current code generation.
This is inconsistent as we detect a problem, but we let the code generation of the current method to proceed.
Comment 4 Olivier Thomann CLA 2010-09-10 15:08:13 EDT
Created attachment 178645 [details]
Proposed fix + regression tests

I made some cleanups in the tests at the same time. So to review, please focus more on the changes in the compiler than the tests themselves.
I try to understand why we are always used the outermost method scope to report the problem.
I think we should always report the problem on the inner most method as this is the one that is checked for the ignoreFurtherInvestigation value.
Comment 5 Olivier Thomann CLA 2010-09-10 15:08:44 EDT
Srikanth, please review.
Comment 6 Olivier Thomann CLA 2010-09-10 15:23:59 EDT
Created attachment 178650 [details]
Proposed fix + regression tests

Same patch with updated copyrights.
Comment 7 Olivier Thomann CLA 2010-09-13 09:19:08 EDT
Released for 3.7M2.
Updated all existing regression tests and added new regression test in:
org.eclipse.jdt.core.tests.compiler.regression.StackMapAttributeTest#test047
Comment 8 Satyam Kandula CLA 2010-09-15 04:14:23 EDT
Verified for 3.7M2 using build  I20100914-0100
Comment 9 Srikanth Sankaran CLA 2010-09-16 02:38:10 EDT
Looks good.