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

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java (-8 / +9 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 332637 - Dead Code detection removing code that isn't dead
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.ast;
12
package org.eclipse.jdt.internal.compiler.ast;
12
13
Lines 126-140 Link Here
126
								addPotentialInitializationsFrom(
127
								addPotentialInitializationsFrom(
127
									handlingContext.initsOnReturn));
128
									handlingContext.initsOnReturn));
128
				} else {
129
				} else {
130
					FlowInfo initsOnException = handlingContext.initsOnException(this.caughtExceptionTypes[i]);
129
					catchInfo =
131
					catchInfo =
130
						flowInfo.unconditionalCopy().
132
						flowInfo.nullInfoLessUnconditionalCopy()
131
							addPotentialInitializationsFrom(
133
							.addPotentialInitializationsFrom(initsOnException)
132
								handlingContext.initsOnException(
134
							.addNullInfoFrom(initsOnException)	// null info only from here, this is the only way to enter the catch block
133
									this.caughtExceptionTypes[i]))
134
							.addPotentialInitializationsFrom(tryInfo.unconditionalCopy())
135
							.addPotentialInitializationsFrom(
135
							.addPotentialInitializationsFrom(
136
								handlingContext.initsOnReturn.
136
									tryInfo.nullInfoLessUnconditionalCopy())
137
									nullInfoLessUnconditionalCopy());
137
							.addPotentialInitializationsFrom(
138
									handlingContext.initsOnReturn.nullInfoLessUnconditionalCopy());
138
				}
139
				}
139
140
140
				// catch var is always set
141
				// catch var is always set
(-)compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java (+8 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 332637 - Dead Code detection removing code that isn't dead
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.flow;
12
package org.eclipse.jdt.internal.compiler.flow;
12
13
Lines 35-40 Link Here
35
	return this;
36
	return this;
36
}
37
}
37
38
39
public FlowInfo addNullInfoFrom(FlowInfo otherInits) {
40
41
	this.initsWhenTrue.addNullInfoFrom(otherInits);
42
	this.initsWhenFalse.addNullInfoFrom(otherInits);
43
	return this;
44
}
45
38
public FlowInfo addPotentialInitializationsFrom(FlowInfo otherInits) {
46
public FlowInfo addPotentialInitializationsFrom(FlowInfo otherInits) {
39
47
40
	this.initsWhenTrue.addPotentialInitializationsFrom(otherInits);
48
	this.initsWhenTrue.addPotentialInitializationsFrom(otherInits);
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java (+8 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 332637 - Dead Code detection removing code that isn't dead
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.flow;
12
package org.eclipse.jdt.internal.compiler.flow;
12
13
Lines 41-46 Link Here
41
 */
42
 */
42
abstract public FlowInfo addInitializationsFrom(FlowInfo otherInits);
43
abstract public FlowInfo addInitializationsFrom(FlowInfo otherInits);
43
44
45
/**
46
 * Add all null information from otherInits to this flow info and return this.
47
 * The operation models the effect of an unconditional sequence of this flow info
48
 * and otherInits.
49
 */
50
abstract public FlowInfo addNullInfoFrom(FlowInfo otherInits);
51
44
52
45
/**
53
/**
46
 * Compose other inits over this flow info, then return this. The operation
54
 * Compose other inits over this flow info, then return this. The operation
(-)compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java (-12 / +25 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 332637   
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.flow;
12
package org.eclipse.jdt.internal.compiler.flow;
12
13
Lines 87-102 Link Here
87
	public int[] nullStatusChangedInAssert; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=303448
88
	public int[] nullStatusChangedInAssert; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=303448
88
89
89
public FlowInfo addInitializationsFrom(FlowInfo inits) {
90
public FlowInfo addInitializationsFrom(FlowInfo inits) {
91
	return addInfoFrom(inits, true);
92
}
93
public FlowInfo addNullInfoFrom(FlowInfo inits) {
94
	return addInfoFrom(inits, false);
95
}
96
private FlowInfo addInfoFrom(FlowInfo inits, boolean handleInits) {
90
	if (this == DEAD_END)
97
	if (this == DEAD_END)
91
		return this;
98
		return this;
92
	if (inits == DEAD_END)
99
	if (inits == DEAD_END)
93
		return this;
100
		return this;
94
	UnconditionalFlowInfo otherInits = inits.unconditionalInits();
101
	UnconditionalFlowInfo otherInits = inits.unconditionalInits();
95
102
96
	// union of definitely assigned variables,
103
	if (handleInits) {
97
	this.definiteInits |= otherInits.definiteInits;
104
		// union of definitely assigned variables,
98
	// union of potentially set ones
105
		this.definiteInits |= otherInits.definiteInits;
99
	this.potentialInits |= otherInits.potentialInits;
106
		// union of potentially set ones
107
		this.potentialInits |= otherInits.potentialInits;
108
	}
109
	
100
	// combine null information
110
	// combine null information
101
	boolean thisHadNulls = (this.tagBits & NULL_FLAG_MASK) != 0,
111
	boolean thisHadNulls = (this.tagBits & NULL_FLAG_MASK) != 0,
102
		otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0;
112
		otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0;
Lines 218-231 Link Here
218
			}
228
			}
219
		}
229
		}
220
		int i;
230
		int i;
221
		// manage definite assignment info
231
		if (handleInits) {
222
		for (i = 0; i < mergeLimit; i++) {
232
			// manage definite assignment info
223
			this.extra[0][i] |= otherInits.extra[0][i];
233
			for (i = 0; i < mergeLimit; i++) {
224
			this.extra[1][i] |= otherInits.extra[1][i];
234
				this.extra[0][i] |= otherInits.extra[0][i];
225
		}
235
				this.extra[1][i] |= otherInits.extra[1][i];
226
		for (; i < copyLimit; i++) {
236
			}
227
			this.extra[0][i] = otherInits.extra[0][i];
237
			for (; i < copyLimit; i++) {
228
			this.extra[1][i] = otherInits.extra[1][i];
238
				this.extra[0][i] = otherInits.extra[0][i];
239
				this.extra[1][i] = otherInits.extra[1][i];
240
			
241
			}
229
		}
242
		}
230
		// tweak limits for nulls
243
		// tweak limits for nulls
231
		if (!thisHadNulls) {
244
		if (!thisHadNulls) {
(-)src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java (-19 / +82 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 332637
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.core.tests.compiler.regression;
12
package org.eclipse.jdt.core.tests.compiler.regression;
12
13
Lines 749-760 Link Here
749
			"    o.toString();\n" +
750
			"    o.toString();\n" +
750
			"  }\n" +
751
			"  }\n" +
751
			"}\n"},
752
			"}\n"},
752
		"----------\n" +
753
			"----------\n" +
753
		"1. ERROR in X.java (at line 4)\n" +
754
		"1. ERROR in X.java (at line 4)\n" +
754
		"	o.toString();\n" +
755
			"	o.toString();\n" +
755
		"	^\n" +
756
			"	^\n" +
756
		"The variable o may be null\n" +
757
		"The variable o may be null\n" +
757
		"----------\n");
758
			"----------\n");
758
}
759
}
759
760
760
// null analysis -- conditional expression
761
// null analysis -- conditional expression
Lines 5598-5604 Link Here
5598
5599
5599
// null analysis - try/catch
5600
// null analysis - try/catch
5600
public void test0554_try_catch() {
5601
public void test0554_try_catch() {
5601
	this.runConformTest(
5602
	this.runNegativeTest(
5602
		new String[] {
5603
		new String[] {
5603
			"X.java",
5604
			"X.java",
5604
			"public class X {\n" +
5605
			"public class X {\n" +
Lines 5622-5635 Link Here
5622
			"    throw new LocalException();\n" +
5623
			"    throw new LocalException();\n" +
5623
			"  }\n" +
5624
			"  }\n" +
5624
			"}\n"},
5625
			"}\n"},
5625
		""
5626
		"----------\n" +
5626
		// conservative flow analysis suppresses the warning
5627
		"1. ERROR in X.java (at line 10)\n" +
5627
//		"----------\n" +
5628
		"	if (o != null) {\n" +
5628
//		"1. ERROR in X.java (at line 10)\n" +
5629
		"	    ^\n" +
5629
//		"	if (o != null) {\n" +
5630
		"Null comparison always yields false: The variable o can only be null at this location\n" +
5630
//		"	    ^\n" +
5631
		"----------\n" +
5631
//		"Redundant null check: The variable o can only be null at this location\n" +
5632
		"2. WARNING in X.java (at line 10)\n" +
5632
//		"----------\n"
5633
		"	if (o != null) {\n" +
5634
		"    }\n" +
5635
		"	               ^^^^^^^\n" +
5636
		"Dead code\n" +
5637
		"----------\n"
5633
	);
5638
	);
5634
}
5639
}
5635
5640
Lines 5748-5756 Link Here
5748
		"1. ERROR in X.java (at line 13)\n" +
5753
		"1. ERROR in X.java (at line 13)\n" +
5749
		"	o.toString();\n" +
5754
		"	o.toString();\n" +
5750
		"	^\n" +
5755
		"	^\n" +
5751
//		"Null pointer access: The variable o can only be null at this location\n" +
5756
		"Null pointer access: The variable o can only be null at this location\n" +
5752
		"Potential null pointer access: The variable o may be null at this location\n" +
5753
		// conservative flow analysis softens the error
5754
		"----------\n",
5757
		"----------\n",
5755
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
5758
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
5756
}
5759
}
Lines 5785-5793 Link Here
5785
		"1. ERROR in X.java (at line 12)\n" +
5788
		"1. ERROR in X.java (at line 12)\n" +
5786
		"	o.toString();\n" +
5789
		"	o.toString();\n" +
5787
		"	^\n" +
5790
		"	^\n" +
5788
//		"Null pointer access: The variable o can only be null at this location\n" +
5791
		"Null pointer access: The variable o can only be null at this location\n" +
5789
		"Potential null pointer access: The variable o may be null at this location\n" +
5790
		// conservative flow analysis softens the error
5791
		"----------\n",
5792
		"----------\n",
5792
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
5793
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
5793
}
5794
}
Lines 12664-12667 Link Here
12664
			"}"},
12665
			"}"},
12665
			"Compiler good Compiler good");
12666
			"Compiler good Compiler good");
12666
}
12667
}
12668
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=332637 
12669
// Dead Code detection removing code that isn't dead
12670
public void testBug332637() {
12671
	if (this.complianceLevel < ClassFileConstants.JDK1_5)
12672
		return;
12673
	this.runConformTest(
12674
		new String[] {
12675
			"DeadCodeExample.java",
12676
			"public class DeadCodeExample {\n" + 
12677
			"\n" + 
12678
			"	private class CanceledException extends Exception {\n" + 
12679
			"	}\n" + 
12680
			"\n" + 
12681
			"	private interface ProgressMonitor {\n" + 
12682
			"		boolean isCanceled();\n" + 
12683
			"	}\n" + 
12684
			"\n" + 
12685
			"	private void checkForCancellation(ProgressMonitor monitor)\n" + 
12686
			"			throws CanceledException {\n" + 
12687
			"		if (monitor.isCanceled()) {\n" + 
12688
			"			throw new CanceledException();\n" + 
12689
			"		}\n" + 
12690
			"	}\n" + 
12691
			"\n" + 
12692
			"	private int run() {\n" + 
12693
			"\n" + 
12694
			"		ProgressMonitor monitor = new ProgressMonitor() {\n" + 
12695
			"			private int i = 0;\n" + 
12696
			"\n" + 
12697
			"			public boolean isCanceled() {\n" + 
12698
			"				return (++i == 5);\n" + 
12699
			"			}\n" + 
12700
			"		};\n" + 
12701
			"\n" + 
12702
			"		Integer number = null;\n" + 
12703
			"\n" + 
12704
			"		try {\n" + 
12705
			"			checkForCancellation(monitor);\n" + 
12706
			"\n" + 
12707
			"			number = Integer.valueOf(0);\n" + 
12708
			"\n" + 
12709
			"			for (String s : new String[10]) {\n" + 
12710
			"				checkForCancellation(monitor);\n" + 
12711
			"				number++;\n" + 
12712
			"			}\n" + 
12713
			"			return 0;\n" + 
12714
			"		} catch (CanceledException e) {\n" + 
12715
			"			System.out.println(\"Canceled after \" + number\n" + 
12716
			"				+ \" times through the loop\");\n" + 
12717
			"			if (number != null) {\n" + 
12718
			"				System.out.println(\"number = \" + number);\n" + 
12719
			"			}\n" + 
12720
			"			return -1;\n" + 
12721
			"		}\n" + 
12722
			"	}\n" + 
12723
			"\n" + 
12724
			"	public static void main(String[] args) {\n" + 
12725
			"		System.out.println(new DeadCodeExample().run());\n" + 
12726
			"	}\n" + 
12727
			"}\n"				
12728
		});
12729
}
12667
}
12730
}

Return to bug 332637