View | Details | Raw Unified | Return to bug 265962 | Differences between
and this patch

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java (-3 / +5 lines)
Lines 1622-1631 Link Here
1622
}
1622
}
1623
1623
1624
public FlowInfo setReachMode(int reachMode) {
1624
public FlowInfo setReachMode(int reachMode) {
1625
	if (reachMode == REACHABLE && this != DEAD_END) { // cannot modify DEAD_END
1625
	if (this == DEAD_END) {// cannot modify DEAD_END
1626
		return this;
1627
	}	
1628
	if (reachMode == REACHABLE ) {
1626
		this.tagBits &= ~UNREACHABLE;
1629
		this.tagBits &= ~UNREACHABLE;
1627
	}
1630
	} else {
1628
	else {
1629
		if ((this.tagBits & UNREACHABLE) == 0) {
1631
		if ((this.tagBits & UNREACHABLE) == 0) {
1630
			// reset optional inits when becoming unreachable
1632
			// reset optional inits when becoming unreachable
1631
			// see InitializationTest#test090 (and others)
1633
			// see InitializationTest#test090 (and others)
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java (-1 / +1 lines)
Lines 58-64 Link Here
58
	}
58
	}
59
59
60
	public static FlowInfo conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){
60
	public static FlowInfo conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){
61
61
		if (initsWhenTrue == initsWhenFalse) return initsWhenTrue;
62
		// if (initsWhenTrue.equals(initsWhenFalse)) return initsWhenTrue; -- could optimize if #equals is defined
62
		// if (initsWhenTrue.equals(initsWhenFalse)) return initsWhenTrue; -- could optimize if #equals is defined
63
		return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse);
63
		return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse);
64
	}
64
	}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java (-25 / +26 lines)
Lines 101-118 Link Here
101
	}
101
	}
102
102
103
	// end of loop
103
	// end of loop
104
	FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranches(
104
	FlowInfo mergedInfo = 
105
			(loopingContext.initsOnBreak.tagBits &
105
		FlowInfo.mergedOptimizedBranches(
106
				FlowInfo.UNREACHABLE) != 0 ?
106
						(loopingContext.initsOnBreak.tagBits & FlowInfo.UNREACHABLE) != 0
107
				loopingContext.initsOnBreak :
107
								? loopingContext.initsOnBreak
108
				flowInfo.unconditionalCopy().addInitializationsFrom(loopingContext.initsOnBreak),
108
								: flowInfo.unconditionalCopy().addInitializationsFrom(loopingContext.initsOnBreak),
109
					// recover upstream null info
109
								// recover upstream null info
110
			isConditionOptimizedTrue,
110
						isConditionOptimizedTrue,
111
			(condInfo.tagBits & FlowInfo.UNREACHABLE) == 0 ?
111
						(condInfo.tagBits & FlowInfo.UNREACHABLE) == 0
112
					flowInfo.addInitializationsFrom(condInfo.initsWhenFalse()) : condInfo,
112
								? flowInfo.addInitializationsFrom(condInfo.initsWhenFalse()) 
113
				// recover null inits from before condition analysis
113
								: condInfo,
114
			false, // never consider opt false case for DO loop, since break can always occur (47776)
114
							// recover null inits from before condition analysis
115
			!isConditionTrue /*do{}while(true); unreachable(); */);
115
						false, // never consider opt false case for DO loop, since break can always occur (47776)
116
						!isConditionTrue /*do{}while(true); unreachable(); */);
116
	this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
117
	this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
117
	return mergedInfo;
118
	return mergedInfo;
118
}
119
}
Lines 144-162 Link Here
144
	// continue label (135602)
145
	// continue label (135602)
145
	if (hasContinueLabel) {
146
	if (hasContinueLabel) {
146
		this.continueLabel.place();
147
		this.continueLabel.place();
147
	}
148
		// generate condition
148
	// generate condition
149
		Constant cst = this.condition.optimizedBooleanConstant();
149
	Constant cst = this.condition.optimizedBooleanConstant();
150
		boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
150
	boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
151
		if (isConditionOptimizedFalse){
151
	if (isConditionOptimizedFalse){
152
			this.condition.generateCode(currentScope, codeStream, false);
152
		this.condition.generateCode(currentScope, codeStream, false);
153
		} else {
153
	} else if (hasContinueLabel) {
154
			this.condition.generateOptimizedBoolean(
154
		this.condition.generateOptimizedBoolean(
155
				currentScope,
155
			currentScope,
156
				codeStream,
156
			codeStream,
157
				actionLabel,
157
			actionLabel,
158
				null,
158
			null,
159
				true);
159
			true);
160
		}
160
	}
161
	}
161
	// May loose some local variable initializations : affecting the local variable attributes
162
	// May loose some local variable initializations : affecting the local variable attributes
162
	if (this.mergedInitStateIndex != -1) {
163
	if (this.mergedInitStateIndex != -1) {
(-)src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java (+63 lines)
Lines 1958-1963 Link Here
1958
		"Unreachable code\n" + 
1958
		"Unreachable code\n" + 
1959
		"----------\n");
1959
		"----------\n");
1960
}
1960
}
1961
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=265962
1962
public void test061() throws Exception {
1963
	this.runConformTest(
1964
		new String[] {
1965
			"X.java",
1966
			"public class X {\n" + 
1967
			"        private static final boolean isIS() {\n" + 
1968
			"                return System.currentTimeMillis()<0 ;\n" + 
1969
			"        }\n" + 
1970
			"        public static void main(String[] args) {\n" + 
1971
			"                do {\n" + 
1972
			"                        return;\n" + 
1973
			"                } while(isIS() && false);\n" + 
1974
			"        }\n" + 
1975
			"}\n", // =================
1976
		},
1977
		"");
1978
	// 	ensure optimized boolean codegen sequence
1979
	String expectedOutput =
1980
		"  public static void main(java.lang.String[] args);\n" + 
1981
		"    0  return\n" + 
1982
		"      Line numbers:\n" + 
1983
		"        [pc: 0, line: 7]\n" + 
1984
		"      Local variable table:\n" + 
1985
		"        [pc: 0, pc: 1] local: args index: 0 type: java.lang.String[]\n";
1986
1987
	File f = new File(OUTPUT_DIR + File.separator + "X.class");
1988
	byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
1989
	ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
1990
	String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
1991
	int index = result.indexOf(expectedOutput);
1992
	if (index == -1 || expectedOutput.length() == 0) {
1993
		System.out.println(Util.displayString(result, 3));
1994
	}
1995
	if (index == -1) {
1996
		assertEquals("Wrong contents", expectedOutput, result);
1997
	}
1998
}
1999
2000
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=265962 - variation
2001
public void test062() {
2002
	runNegativeTest(
2003
		new String[] { /* test files */
2004
			"X.java",
2005
			"public class X {\n" + 
2006
			"        private static final boolean isIS() {\n" + 
2007
			"                return System.currentTimeMillis()<0 ;\n" + 
2008
			"        }\n" + 
2009
			"        public static void main(String[] args) {\n" + 
2010
			"                do {\n" + 
2011
			"                        return;\n" + 
2012
			"                } while(isIS() && false);\n" + 
2013
			"                return;\n" + 
2014
			"        }\n" + 
2015
			"}\n"
2016
		},
2017
		"----------\n" + 
2018
		"1. ERROR in X.java (at line 9)\n" + 
2019
		"	return;\n" + 
2020
		"	^^^^^^^\n" + 
2021
		"Unreachable code\n" + 
2022
		"----------\n");
2023
}
1961
public static Class testClass() {
2024
public static Class testClass() {
1962
	return FlowAnalysisTest.class;
2025
	return FlowAnalysisTest.class;
1963
}
2026
}

Return to bug 265962