### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java,v retrieving revision 1.62 diff -u -r1.62 UnconditionalFlowInfo.java --- compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java 1 Dec 2008 12:32:13 -0000 1.62 +++ compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java 4 Mar 2009 16:29:39 -0000 @@ -1622,10 +1622,12 @@ } public FlowInfo setReachMode(int reachMode) { - if (reachMode == REACHABLE && this != DEAD_END) { // cannot modify DEAD_END + if (this == DEAD_END) {// cannot modify DEAD_END + return this; + } + if (reachMode == REACHABLE ) { this.tagBits &= ~UNREACHABLE; - } - else { + } else { if ((this.tagBits & UNREACHABLE) == 0) { // reset optional inits when becoming unreachable // see InitializationTest#test090 (and others) Index: compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java,v retrieving revision 1.36 diff -u -r1.36 FlowInfo.java --- compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java 27 Jun 2008 16:04:13 -0000 1.36 +++ compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java 4 Mar 2009 16:29:39 -0000 @@ -58,7 +58,7 @@ } public static FlowInfo conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){ - + if (initsWhenTrue == initsWhenFalse) return initsWhenTrue; // if (initsWhenTrue.equals(initsWhenFalse)) return initsWhenTrue; -- could optimize if #equals is defined return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse); } Index: compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java,v retrieving revision 1.57 diff -u -r1.57 DoStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java 27 Jun 2008 16:03:55 -0000 1.57 +++ compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java 4 Mar 2009 16:29:39 -0000 @@ -101,18 +101,19 @@ } // end of loop - FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranches( - (loopingContext.initsOnBreak.tagBits & - FlowInfo.UNREACHABLE) != 0 ? - loopingContext.initsOnBreak : - flowInfo.unconditionalCopy().addInitializationsFrom(loopingContext.initsOnBreak), - // recover upstream null info - isConditionOptimizedTrue, - (condInfo.tagBits & FlowInfo.UNREACHABLE) == 0 ? - flowInfo.addInitializationsFrom(condInfo.initsWhenFalse()) : condInfo, - // recover null inits from before condition analysis - false, // never consider opt false case for DO loop, since break can always occur (47776) - !isConditionTrue /*do{}while(true); unreachable(); */); + FlowInfo mergedInfo = + FlowInfo.mergedOptimizedBranches( + (loopingContext.initsOnBreak.tagBits & FlowInfo.UNREACHABLE) != 0 + ? loopingContext.initsOnBreak + : flowInfo.unconditionalCopy().addInitializationsFrom(loopingContext.initsOnBreak), + // recover upstream null info + isConditionOptimizedTrue, + (condInfo.tagBits & FlowInfo.UNREACHABLE) == 0 + ? flowInfo.addInitializationsFrom(condInfo.initsWhenFalse()) + : condInfo, + // recover null inits from before condition analysis + false, // never consider opt false case for DO loop, since break can always occur (47776) + !isConditionTrue /*do{}while(true); unreachable(); */); this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo); return mergedInfo; } @@ -144,19 +145,19 @@ // continue label (135602) if (hasContinueLabel) { this.continueLabel.place(); - } - // generate condition - Constant cst = this.condition.optimizedBooleanConstant(); - boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false; - if (isConditionOptimizedFalse){ - this.condition.generateCode(currentScope, codeStream, false); - } else if (hasContinueLabel) { - this.condition.generateOptimizedBoolean( - currentScope, - codeStream, - actionLabel, - null, - true); + // generate condition + Constant cst = this.condition.optimizedBooleanConstant(); + boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false; + if (isConditionOptimizedFalse){ + this.condition.generateCode(currentScope, codeStream, false); + } else { + this.condition.generateOptimizedBoolean( + currentScope, + codeStream, + actionLabel, + null, + true); + } } // May loose some local variable initializations : affecting the local variable attributes if (this.mergedInitStateIndex != -1) { #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java,v retrieving revision 1.37 diff -u -r1.37 FlowAnalysisTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java 26 Nov 2008 17:57:03 -0000 1.37 +++ src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java 4 Mar 2009 16:29:41 -0000 @@ -1958,6 +1958,69 @@ "Unreachable code\n" + "----------\n"); } +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=265962 +public void test061() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " private static final boolean isIS() {\n" + + " return System.currentTimeMillis()<0 ;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " do {\n" + + " return;\n" + + " } while(isIS() && false);\n" + + " }\n" + + "}\n", // ================= + }, + ""); + // ensure optimized boolean codegen sequence + String expectedOutput = + " public static void main(java.lang.String[] args);\n" + + " 0 return\n" + + " Line numbers:\n" + + " [pc: 0, line: 7]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 1] local: args index: 0 type: java.lang.String[]\n"; + + File f = new File(OUTPUT_DIR + File.separator + "X.class"); + byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f); + ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); + String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED); + int index = result.indexOf(expectedOutput); + if (index == -1 || expectedOutput.length() == 0) { + System.out.println(Util.displayString(result, 3)); + } + if (index == -1) { + assertEquals("Wrong contents", expectedOutput, result); + } +} + +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=265962 - variation +public void test062() { + runNegativeTest( + new String[] { /* test files */ + "X.java", + "public class X {\n" + + " private static final boolean isIS() {\n" + + " return System.currentTimeMillis()<0 ;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " do {\n" + + " return;\n" + + " } while(isIS() && false);\n" + + " return;\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 9)\n" + + " return;\n" + + " ^^^^^^^\n" + + "Unreachable code\n" + + "----------\n"); +} public static Class testClass() { return FlowAnalysisTest.class; }