### Eclipse Workspace Patch 1.0 #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.22 diff -u -r1.22 FlowAnalysisTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java 27 Apr 2007 15:57:14 -0000 1.22 +++ src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java 8 Oct 2007 08:56:58 -0000 @@ -1361,6 +1361,77 @@ }, ""); } +// labeled loop +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=200158 +// contrast this with test049 +public void test048() { + runTest( + new String[] { + "X.java", + "public class X {\n" + + " private static final boolean b = false;\n" + + " public Object foo() {\n" + + " if (b) {\n" + + " label: while (bar()) {\n" + + " }\n" + + " return null;\n" + + " }\n" + + " return null;\n" + + " }\n" + + " boolean bar() {\n" + + " return false;\n" + + " }\n" + + "}\n" + }, + false /* expectingCompilerErrors */, + "----------\n" + + "1. WARNING in X.java (at line 5)\n" + + " label: while (bar()) {\n" + + " ^^^^^\n" + + "The label label is never explicitly referenced\n" + + "----------\n" /* expectedCompilerLog */, + "" /* expectedOutputString */, + false /* forceExecution */, + null /* classLib */, + true /* shouldFlushOutputDirectory */, + null /* vmArguments */, + null /* customOptions */, + null /* clientRequestor */, + true /* skipJavac */); +} +// labeled loop +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=200158 +// variant: this one passes +public void test049() { + runTest( + new String[] { + "X.java", + "public class X {\n" + + " private static final boolean b = false;\n" + + " public Object foo() {\n" + + " if (b) {\n" + + " while (bar()) {\n" + + " }\n" + + " return null;\n" + + " }\n" + + " return null;\n" + + " }\n" + + " boolean bar() {\n" + + " return false;\n" + + " }\n" + + "}\n" + }, + false /* expectingCompilerErrors */, + "" /* expectedCompilerLog */, + "" /* expectedOutputString */, + false /* forceExecution */, + null /* classLib */, + true /* shouldFlushOutputDirectory */, + null /* vmArguments */, + null /* customOptions */, + null /* clientRequestor */, + true /* skipJavac */); +} public static Class testClass() { return FlowAnalysisTest.class; } Index: src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java,v retrieving revision 1.75 diff -u -r1.75 AbstractRegressionTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java 19 Mar 2007 17:51:08 -0000 1.75 +++ src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java 8 Oct 2007 08:56:58 -0000 @@ -229,9 +229,6 @@ } } - /*###################################### - * Specific method to let tests Sun javac compilation available... - #######################################*/ protected void compileAndDeploy(String source, String directoryName, String className) { File directory = new File(SOURCE_DIRECTORY); if (!directory.exists()) { @@ -266,8 +263,12 @@ .append(EVAL_DIRECTORY); if (this.complianceLevel.compareTo(COMPLIANCE_1_5) < 0) { buffer.append("\" -1.4 -source 1.3 -target 1.2"); - } else { + } else if (this.complianceLevel.compareTo(COMPLIANCE_1_5) == 0) { buffer.append("\" -1.5"); + } else if (this.complianceLevel.compareTo(COMPLIANCE_1_6) == 0) { + buffer.append("\" -1.6"); + } else if (this.complianceLevel.compareTo(COMPLIANCE_1_7) == 0) { + buffer.append("\" -1.7"); } buffer .append(" -preserveAllLocals -nowarn -g -classpath \"") @@ -1243,6 +1244,133 @@ } } + protected void runTest( + String[] testFiles, + boolean expectingCompilerErrors, + String expectedCompilerLog, + String expectedOutputString, + boolean forceExecution, + String[] classLib, + boolean shouldFlushOutputDirectory, + String[] vmArguments, + Map customOptions, + ICompilerRequestor clientRequestor, + boolean skipJavac) { + // Non-javac part + try { + if (shouldFlushOutputDirectory) + Util.flushDirectoryContent(new File(OUTPUT_DIR)); + + IProblemFactory problemFactory = getProblemFactory(); + Requestor requestor = + new Requestor( + problemFactory, + OUTPUT_DIR.endsWith(File.separator) ? OUTPUT_DIR : OUTPUT_DIR + File.separator, + forceExecution, + clientRequestor, + false, /* show category */ + false /* show warning token*/); + + Map options = getCompilerOptions(); + if (customOptions != null) { + options.putAll(customOptions); + } + CompilerOptions compilerOptions = new CompilerOptions(options); + compilerOptions.performMethodsFullRecovery = false; + compilerOptions.performStatementsRecovery = false; + Compiler batchCompiler = + new Compiler( + getNameEnvironment(new String[]{}, classLib), + getErrorHandlingPolicy(), + compilerOptions, + requestor, + problemFactory); + compilerOptions.produceReferenceInfo = true; + Throwable exception = null; + try { + batchCompiler.compile(Util.compilationUnits(testFiles)); // compile all files together + } catch(RuntimeException e){ + exception = e; + throw e; + } catch(Error e) { + exception = e; + throw e; + } finally { + String computedProblemLog = Util.convertToIndependantLineDelimiter(requestor.problemLog.toString()); + String platformIndependantExpectedLog = Util.convertToIndependantLineDelimiter(expectedCompilerLog); + if (!platformIndependantExpectedLog.equals(computedProblemLog)) { + System.out.println(getClass().getName() + '#' + getName()); + System.out.println(Util.displayString(computedProblemLog, INDENT, SHIFT)); + for (int i = 0; i < testFiles.length; i += 2) { + System.out.print(testFiles[i]); + System.out.println(" ["); //$NON-NLS-1$ + System.out.println(testFiles[i + 1]); + System.out.println("]"); //$NON-NLS-1$ + } + } + if (exception == null) { + if (expectingCompilerErrors) { + assertTrue("Unexpected success", requestor.hasErrors); + } else { + assertFalse("Unexpected failure", requestor.hasErrors); + } + assertEquals("Invalid problem log ", platformIndependantExpectedLog, computedProblemLog); + } + } + if (!requestor.hasErrors || forceExecution) { + String sourceFile = testFiles[0]; + + // Compute class name by removing ".java" and replacing slashes with dots + String className = sourceFile.substring(0, sourceFile.length() - 5).replace('/', '.').replace('\\', '.'); + if (className.endsWith(PACKAGE_INFO_NAME)) return; + + if (vmArguments != null) { + if (this.verifier != null) { + this.verifier.shutDown(); + } + this.verifier = new TestVerifier(false); + this.createdVerifier = true; + } + boolean passed = + this.verifier.verifyClassFiles( + sourceFile, + className, + expectedOutputString, + this.classpaths, + null, + vmArguments); + if (!passed) { + System.out.println(getClass().getName() + '#' + getName()); + for (int i = 0; i < testFiles.length; i += 2) { + System.out.print(testFiles[i]); + System.out.println(" ["); //$NON-NLS-1$ + System.out.println(testFiles[i + 1]); + System.out.println("]"); //$NON-NLS-1$ + } + } + assertTrue(this.verifier.failureReason, // computed by verifyClassFiles(...) action + passed); + if (vmArguments != null) { + if (this.verifier != null) { + this.verifier.shutDown(); + } + this.verifier = new TestVerifier(false); + this.createdVerifier = true; + } + } + // javac part + } catch (AssertionFailedError e) { + throw e; + } finally { + if (RUN_JAVAC && !skipJavac) + runJavac(testFiles, null, expectedOutputString, shouldFlushOutputDirectory); + // PREMATURE for now, skipping javac implies skipping the compile + // and execution steps; yet, only cases for which the + // execution step was a problem have been discovered so + // far; may consider skipping the execution step only + } + } + protected void setUp() throws Exception { super.setUp(); if (this.verifier == null) { #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java,v retrieving revision 1.37 diff -u -r1.37 LabeledStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java 5 Oct 2006 06:33:38 -0000 1.37 +++ compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java 8 Oct 2007 08:57:02 -0000 @@ -51,26 +51,23 @@ } else { LabelFlowContext labelContext; FlowInfo statementInfo, mergedInfo; - if (((statementInfo = statement - .analyseCode( - currentScope, - (labelContext = - new LabelFlowContext( - flowContext, - this, - label, - (targetLabel = new BranchLabel()), - currentScope)), - flowInfo)).tagBits & FlowInfo.UNREACHABLE) != 0) { - if ((labelContext.initsOnBreak.tagBits & FlowInfo.UNREACHABLE) == 0) { - // an embedded loop has had no chance to reinject forgotten null info - mergedInfo = flowInfo.unconditionalCopy(). - addInitializationsFrom(labelContext.initsOnBreak); - } else { - mergedInfo = labelContext.initsOnBreak; - } - } else { - mergedInfo = statementInfo.mergedWith(labelContext.initsOnBreak); + statementInfo = statement.analyseCode( + currentScope, + (labelContext = + new LabelFlowContext( + flowContext, + this, + label, + (targetLabel = new BranchLabel()), + currentScope)), + flowInfo); + boolean reinjectNullInfo = (statementInfo.tagBits & FlowInfo.UNREACHABLE) != 0 && + (labelContext.initsOnBreak.tagBits & FlowInfo.UNREACHABLE) == 0; + mergedInfo = statementInfo.mergedWith(labelContext.initsOnBreak); + if (reinjectNullInfo) { + // an embedded loop has had no chance to reinject forgotten null info + ((UnconditionalFlowInfo)mergedInfo).addInitializationsFrom(flowInfo.unconditionalFieldLessCopy()). + addInitializationsFrom(labelContext.initsOnBreak.unconditionalFieldLessCopy()); } mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);