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

Collapse All | Expand All

(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java (-1 / +147 lines)
Lines 47-53 Link Here
47
// Only the highest compliance level is run; add the VM argument
47
// Only the highest compliance level is run; add the VM argument
48
// -Dcompliance=1.4 (for example) to lower it if needed
48
// -Dcompliance=1.4 (for example) to lower it if needed
49
static {
49
static {
50
//		TESTS_NAMES = new String[] { "test358827" };
50
//		TESTS_NAMES = new String[] { "testBug256796" };
51
//		TESTS_NUMBERS = new int[] { 561 };
51
//		TESTS_NUMBERS = new int[] { 561 };
52
//		TESTS_RANGE = new int[] { 1, 2049 };
52
//		TESTS_RANGE = new int[] { 1, 2049 };
53
}
53
}
Lines 14978-14981 Link Here
14978
				"----------\n");
14978
				"----------\n");
14979
	}
14979
	}
14980
}
14980
}
14981
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796
14982
public void testBug256796() {
14983
	Map compilerOptions = getCompilerOptions();
14984
	compilerOptions.put(CompilerOptions.OPTION_ReportUnnecessaryElse, CompilerOptions.IGNORE);
14985
	compilerOptions.put(CompilerOptions.OPTION_ReportDeadCode, CompilerOptions.WARNING);
14986
	compilerOptions.put(CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement, CompilerOptions.DISABLED);
14987
	this.runNegativeTest(
14988
			new String[] {
14989
				"Bug.java",
14990
				"public class Bug {\n" +
14991
				"	private static final boolean TRUE = true;\n" +
14992
				"   private static final boolean FALSE = false;\n" +
14993
				"	void foo() throws Exception {\n" + 
14994
				"		if (TRUE) return;\n" +
14995
				"		else System.out.println(\"\");\n" +
14996
				"		System.out.println(\"\");\n" + 		// not dead code
14997
				"		if (TRUE) throw new Exception();\n" +
14998
				"		else System.out.println(\"\");\n" +
14999
				"		System.out.println(\"\");\n" + 		// not dead code
15000
				"		if (TRUE) return;\n" +
15001
				"		System.out.println(\"\");\n" + 		// not dead code
15002
				"		if (FALSE) System.out.println(\"\");\n" +
15003
				"		else return;\n" +
15004
				"		System.out.println(\"\");\n" + 		// not dead code
15005
				"		if (FALSE) return;\n" +
15006
				"		System.out.println(\"\");\n" + 		// not dead code
15007
				"		if (false) return;\n" +				// dead code
15008
				"		System.out.println(\"\");\n" + 		
15009
				"		if (true) return;\n" +
15010
				"		System.out.println(\"\");\n" + 		// dead code
15011
				"	}\n" + 
15012
				"}\n"
15013
			},
15014
			"----------\n" + 
15015
			"1. WARNING in Bug.java (at line 18)\n" + 
15016
			"	if (false) return;\n" + 
15017
			"	           ^^^^^^^\n" + 
15018
			"Dead code\n" + 
15019
			"----------\n" + 
15020
			"2. WARNING in Bug.java (at line 21)\n" + 
15021
			"	System.out.println(\"\");\n" + 
15022
			"	^^^^^^^^^^^^^^^^^^^^^^\n" + 
15023
			"Dead code\n" + 
15024
			"----------\n",
15025
			null,
15026
			true,
15027
			compilerOptions);
15028
}
15029
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796
15030
public void testBug256796a() {
15031
	Map compilerOptions = getCompilerOptions();
15032
	compilerOptions.put(CompilerOptions.OPTION_ReportUnnecessaryElse, CompilerOptions.IGNORE);
15033
	compilerOptions.put(CompilerOptions.OPTION_ReportDeadCode, CompilerOptions.WARNING);
15034
	compilerOptions.put(CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement, CompilerOptions.ENABLED);
15035
	this.runNegativeTest(
15036
			new String[] {
15037
				"Bug.java",
15038
				"public class Bug {\n" +
15039
				"	private static final boolean TRUE = true;\n" +
15040
				"   private static final boolean FALSE = false;\n" +
15041
				"	void foo() throws Exception {\n" + 
15042
				"		if (TRUE) return;\n" +
15043
				"		else System.out.println(\"\");\n" +
15044
				"		System.out.println(\"\");\n" + 		// dead code
15045
				"	}\n" +
15046
				"   void foo2() {\n" +
15047
				"		if (TRUE) return;\n" +
15048
				"		System.out.println(\"\");\n" + 		// dead code
15049
				"	}\n" +
15050
				"	void foo3() throws Exception {\n" + 
15051
				"		if (TRUE) throw new Exception();\n" +
15052
				"		else System.out.println(\"\");\n" + // dead code
15053
				"		System.out.println(\"\");\n" + 		// dead code
15054
				"	}\n" + 
15055
				"	void foo4() throws Exception {\n" + 
15056
				"		if (FALSE) System.out.println(\"\");\n" +
15057
				"		else return;\n" +
15058
				"		System.out.println(\"\");\n" + 		// dead code
15059
				"	}\n" + 
15060
				"	void foo5() throws Exception {\n" + 
15061
				"		if (FALSE) return;\n" +				// dead code
15062
				"		System.out.println(\"\");\n" + 		
15063
				"	}\n" +
15064
				"	void foo6() throws Exception {\n" + 
15065
				"		if (false) return;\n" +				// dead code
15066
				"		System.out.println(\"\");\n" + 		
15067
				"		if (true) return;\n" +
15068
				"		System.out.println(\"\");\n" + 		// dead code
15069
				"	}\n" +
15070
				"}\n"
15071
			},
15072
			"----------\n" + 
15073
			"1. WARNING in Bug.java (at line 6)\n" + 
15074
			"	else System.out.println(\"\");\n" + 
15075
			"	     ^^^^^^^^^^^^^^^^^^^^^^\n" + 
15076
			"Dead code\n" + 
15077
			"----------\n" + 
15078
			"2. WARNING in Bug.java (at line 7)\n" + 
15079
			"	System.out.println(\"\");\n" + 
15080
			"	^^^^^^^^^^^^^^^^^^^^^^\n" + 
15081
			"Dead code\n" + 
15082
			"----------\n" + 
15083
			"3. WARNING in Bug.java (at line 11)\n" + 
15084
			"	System.out.println(\"\");\n" + 
15085
			"	^^^^^^^^^^^^^^^^^^^^^^\n" + 
15086
			"Dead code\n" + 
15087
			"----------\n" + 
15088
			"4. WARNING in Bug.java (at line 15)\n" + 
15089
			"	else System.out.println(\"\");\n" + 
15090
			"	     ^^^^^^^^^^^^^^^^^^^^^^\n" + 
15091
			"Dead code\n" + 
15092
			"----------\n" + 
15093
			"5. WARNING in Bug.java (at line 16)\n" + 
15094
			"	System.out.println(\"\");\n" + 
15095
			"	^^^^^^^^^^^^^^^^^^^^^^\n" + 
15096
			"Dead code\n" + 
15097
			"----------\n" + 
15098
			"6. WARNING in Bug.java (at line 19)\n" + 
15099
			"	if (FALSE) System.out.println(\"\");\n" + 
15100
			"	           ^^^^^^^^^^^^^^^^^^^^^^\n" + 
15101
			"Dead code\n" + 
15102
			"----------\n" + 
15103
			"7. WARNING in Bug.java (at line 21)\n" + 
15104
			"	System.out.println(\"\");\n" + 
15105
			"	^^^^^^^^^^^^^^^^^^^^^^\n" + 
15106
			"Dead code\n" + 
15107
			"----------\n" + 
15108
			"8. WARNING in Bug.java (at line 24)\n" + 
15109
			"	if (FALSE) return;\n" + 
15110
			"	           ^^^^^^^\n" + 
15111
			"Dead code\n" + 
15112
			"----------\n" + 
15113
			"9. WARNING in Bug.java (at line 28)\n" + 
15114
			"	if (false) return;\n" + 
15115
			"	           ^^^^^^^\n" + 
15116
			"Dead code\n" + 
15117
			"----------\n" + 
15118
			"10. WARNING in Bug.java (at line 31)\n" + 
15119
			"	System.out.println(\"\");\n" + 
15120
			"	^^^^^^^^^^^^^^^^^^^^^^\n" + 
15121
			"Dead code\n" + 
15122
			"----------\n",
15123
			null,
15124
			true,
15125
			compilerOptions);
15126
}
14981
}
15127
}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java (-3 / +5 lines)
Lines 86-96 Link Here
86
		// No need if the whole if-else construct itself lies in unreachable code
86
		// No need if the whole if-else construct itself lies in unreachable code
87
		this.bits |= ASTNode.IsElseStatementUnreachable;
87
		this.bits |= ASTNode.IsElseStatementUnreachable;
88
	}
88
	}
89
	boolean reportDeadCodeForKnownPattern = !isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement;
89
	if (this.thenStatement != null) {
90
	if (this.thenStatement != null) {
90
		// Save info for code gen
91
		// Save info for code gen
91
		this.thenInitStateIndex = currentScope.methodScope().recordInitializationStates(thenFlowInfo);
92
		this.thenInitStateIndex = currentScope.methodScope().recordInitializationStates(thenFlowInfo);
92
		if (isConditionOptimizedFalse || ((this.bits & ASTNode.IsThenStatementUnreachable) != 0)) {
93
		if (isConditionOptimizedFalse || ((this.bits & ASTNode.IsThenStatementUnreachable) != 0)) {
93
			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
94
			if (reportDeadCodeForKnownPattern) {
94
				this.thenStatement.complainIfUnreachable(thenFlowInfo, flowContext, currentScope, initialComplaintLevel, false);
95
				this.thenStatement.complainIfUnreachable(thenFlowInfo, flowContext, currentScope, initialComplaintLevel, false);
95
			} else {
96
			} else {
96
				// its a known coding pattern which should be tolerated by dead code analysis
97
				// its a known coding pattern which should be tolerated by dead code analysis
Lines 116-122 Link Here
116
		// Save info for code gen
117
		// Save info for code gen
117
		this.elseInitStateIndex = currentScope.methodScope().recordInitializationStates(elseFlowInfo);
118
		this.elseInitStateIndex = currentScope.methodScope().recordInitializationStates(elseFlowInfo);
118
		if (isConditionOptimizedTrue || ((this.bits & ASTNode.IsElseStatementUnreachable) != 0)) {
119
		if (isConditionOptimizedTrue || ((this.bits & ASTNode.IsElseStatementUnreachable) != 0)) {
119
			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
120
			if (reportDeadCodeForKnownPattern) {
120
				this.elseStatement.complainIfUnreachable(elseFlowInfo, flowContext, currentScope, initialComplaintLevel, false);
121
				this.elseStatement.complainIfUnreachable(elseFlowInfo, flowContext, currentScope, initialComplaintLevel, false);
121
			} else {
122
			} else {
122
				// its a known coding pattern which should be tolerated by dead code analysis
123
				// its a known coding pattern which should be tolerated by dead code analysis
Lines 136-142 Link Here
136
		isConditionOptimizedFalse,
137
		isConditionOptimizedFalse,
137
		true /*if(true){ return; }  fake-reachable(); */,
138
		true /*if(true){ return; }  fake-reachable(); */,
138
		flowInfo,
139
		flowInfo,
139
		this);
140
		this,
141
		reportDeadCodeForKnownPattern);
140
	this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
142
	this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
141
	return mergedInfo;
143
	return mergedInfo;
142
}
144
}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java (-5 / +36 lines)
Lines 405-416 Link Here
405
public static UnconditionalFlowInfo mergedOptimizedBranchesIfElse(
405
public static UnconditionalFlowInfo mergedOptimizedBranchesIfElse(
406
		FlowInfo initsWhenTrue, boolean isOptimizedTrue,
406
		FlowInfo initsWhenTrue, boolean isOptimizedTrue,
407
		FlowInfo initsWhenFalse, boolean isOptimizedFalse,
407
		FlowInfo initsWhenFalse, boolean isOptimizedFalse,
408
		boolean allowFakeDeadBranch, FlowInfo flowInfo, IfStatement ifStatement) {
408
		boolean allowFakeDeadBranch, FlowInfo flowInfo, IfStatement ifStatement,
409
		boolean reportDeadCodeInKnownPattern) {
409
	UnconditionalFlowInfo mergedInfo;
410
	UnconditionalFlowInfo mergedInfo;
410
	if (isOptimizedTrue){
411
	if (isOptimizedTrue){
411
		if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
412
		if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
412
			mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
413
			if (!reportDeadCodeInKnownPattern) {
413
				unconditionalInits();
414
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796
415
				// do not report code even after if-else as dead as a consequence of analysis done in known dead code pattern
416
				// when the CompilerOptions$reportDeadCodeInTrivialIfStatement option is disabled
417
				if (ifStatement.elseStatement == null) {
418
					mergedInfo = flowInfo.unconditionalInits();
419
				} else {
420
					mergedInfo = initsWhenFalse.unconditionalInits();
421
					if (initsWhenFalse != FlowInfo.DEAD_END) {
422
						// let the definitely true status of known dead code pattern not affect the reachability
423
						mergedInfo.setReachMode(flowInfo.reachMode());
424
					}
425
				}
426
			} else {
427
				mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
428
					unconditionalInits();
429
			}
414
		}
430
		}
415
		else {
431
		else {
416
			mergedInfo =
432
			mergedInfo =
Lines 421-428 Link Here
421
	}
437
	}
422
	else if (isOptimizedFalse) {
438
	else if (isOptimizedFalse) {
423
		if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
439
		if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
424
			mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
440
			if (!reportDeadCodeInKnownPattern) {
425
				unconditionalInits();
441
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796
442
				// do not report code even after if-else as dead as a consequence of analysis done in known dead code pattern
443
				// when the CompilerOptions$reportDeadCodeInTrivialIfStatement option is disabled
444
				if (ifStatement.thenStatement == null) {
445
					mergedInfo = flowInfo.unconditionalInits();
446
				} else {
447
					mergedInfo = initsWhenTrue.unconditionalInits();
448
					if (initsWhenTrue != FlowInfo.DEAD_END) {
449
						// let the definitely false status of known dead code pattern not affect the reachability
450
						mergedInfo.setReachMode(flowInfo.reachMode());
451
					}
452
				}
453
			} else {
454
				mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
455
					unconditionalInits();
456
			}
426
		}
457
		}
427
		else {
458
		else {
428
			mergedInfo =
459
			mergedInfo =

Return to bug 256796