Bug 40736 - JDT compiler fails to compile legitimate Java code.
Summary: JDT compiler fails to compile legitimate Java code.
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.0   Edit
Hardware: PC Windows NT
: P3 major (vote)
Target Milestone: 2.1.2   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-07-24 18:40 EDT by Deyan Bektchiev CLA
Modified: 2003-10-23 05:35 EDT (History)
1 user (show)

See Also:


Attachments
regression test (735 bytes, text/plain)
2003-07-29 03:40 EDT, Nick Teryaev CLA
no flags Details
regression test update (1.00 KB, text/plain)
2003-07-29 03:52 EDT, Nick Teryaev CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Deyan Bektchiev CLA 2003-07-24 18:40:44 EDT
I guess the compiler can generate a warning for this but an error is a bit too
much for the class below:

package util;

import java.util.Random;

public class EclipseBug
{
    public void showBug() throws MyException
    {
        System.out.println("test");
    }

    protected void throwsMethod() throws MyException
    {
        if(new Random().nextInt() == 500)
        {
            throw new MyException();
        }
    }

    class MyException extends Exception
    {

    }
}

class sub extends EclipseBug
{
    public void showBug() throws MyException
    {
        if(false)
        {
            try
            {
                try
                {
                    throwsMethod();
                }
                finally
                {
                    System.out.println("finally");
                }
            }
            catch(MyException ex)
            { // THIS IS LINE 44 THE COMPILE COMPLAINS
                ex.printStackTrace();
            }
        }

        super.showBug();
    }

}


Result of compilation:

1. ERROR in D:\Dev\2003.2\corejrisk\src\util\EclipseBug.java (at line 44)
    {
                ex.printStackTrace();
            }
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Unreachable catch block
----------
1 problem (1 error)


Compilation goes fine if this same code is in the base class or of the Exception
is not a subclass of Exception.
Comment 1 Philipe Mulet CLA 2003-07-25 05:12:46 EDT
Indeed, we should not complain.
Comment 2 Nick Teryaev CLA 2003-07-29 03:31:18 EDT
test case reduced a little bit:

public class Sample
{
	public void method()
	{
		if (false) {
			try {
				try {
					throw new InterruptedException();
				} finally {
					System.out.println();
				}
			}
			catch(InterruptedException e) {
			}
		}
	}
}
Comment 3 Nick Teryaev CLA 2003-07-29 03:40:25 EDT
Created attachment 5575 [details]
regression test
Comment 4 Nick Teryaev CLA 2003-07-29 03:40:40 EDT
regression test added
Comment 5 Nick Teryaev CLA 2003-07-29 03:52:17 EDT
Created attachment 5576 [details]
regression test update

added a test for if (true) {} else { ...code... } situation
Comment 6 Nick Teryaev CLA 2003-07-29 03:53:18 EDT
proposed patch:

Index: IfStatement.java
===================================================================
RCS 
file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compi
ler/ast/IfStatement.java,v
retrieving revision 1.35
diff -u -r1.35 IfStatement.java
--- IfStatement.java	26 Jun 2003 15:59:51 -0000	1.35
+++ IfStatement.java	29 Jul 2003 07:51:19 -0000
@@ -83,7 +83,7 @@
 			// Save info for code gen
 			thenInitStateIndex =
 				currentScope.methodScope
().recordInitializationStates(thenFlowInfo);
-			if (!thenStatement.complainIfUnreachable(thenFlowInfo, 
currentScope, false)) {
+			if (!isConditionOptimizedFalse && !
thenStatement.complainIfUnreachable(thenFlowInfo, currentScope, false)) {
 				thenFlowInfo =
 					thenStatement.analyseCode(currentScope, 
flowContext, thenFlowInfo);
 			}
@@ -100,7 +100,7 @@
 			// Save info for code gen
 			elseInitStateIndex =
 				currentScope.methodScope
().recordInitializationStates(elseFlowInfo);
-			if (!elseStatement.complainIfUnreachable(elseFlowInfo, 
currentScope, false)) {
+			if (!isConditionOptimizedTrue && !
elseStatement.complainIfUnreachable(elseFlowInfo, currentScope, false)) {
 				elseFlowInfo =
 					elseStatement.analyseCode(currentScope, 
flowContext, elseFlowInfo);
 			}
Comment 7 Philipe Mulet CLA 2003-08-06 05:02:58 EDT
This fix would not work as it would entirely skip the flow analysis inside 
offending fake reachable portions of the ASTs.
The real fix is quite more complex and lives elsewhere. Unreachable code should 
still be processed
during the analysis, slightly differently.

e.g.
if (false) {
	return;
	return; // should still complain about being unreachable
}

The real fix is actually in checks for unreachable flow infos, which should be 
replaced  from "...info.isReachable()" into "...info == FlowInfo.DEAD_END".

Down the road we should get rid of DEAD_ENDs since these are loosing track of 
the initialization information from thereon.
Comment 8 Philipe Mulet CLA 2003-08-28 12:19:04 EDT
Fixed, regression tests added.
Comment 9 Philipe Mulet CLA 2003-09-23 06:43:12 EDT
Backported to 2.1 stream for further integration.
Regression test added.
Comment 10 Philipe Mulet CLA 2003-09-23 19:17:24 EDT
Released for 2.1.2 (backported better version, see bug 42692).
Comment 11 Philipe Mulet CLA 2003-10-18 08:08:21 EDT
Regression tests are InitializationTest#test161/test162.
These were not backported to 2.1.2 stream. Added now.
Comment 12 Philipe Mulet CLA 2003-10-18 08:41:28 EDT
2.1.2 stream was missing portion of the fix on TryStatement.
Backport complete now. 
Comment 13 Frederic Fusier CLA 2003-10-23 05:20:23 EDT
Verified with build 2.1.2 RC2
Comment 14 Jerome Lanneluc CLA 2003-10-23 05:35:03 EDT
Verified as well.