Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 356002 | Differences between
and this patch

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java (-8 / +10 lines)
Lines 175-181 Link Here
175
			}
175
			}
176
176
177
			final boolean hasCases = this.caseCount != 0;
177
			final boolean hasCases = this.caseCount != 0;
178
			final boolean valueRequired = this.expression.constant == Constant.NotAConstant || hasCases;
179
178
180
			StringSwitchCase [] stringCases = new StringSwitchCase[this.caseCount]; // may have to shrink later if multiple strings hash to same code.
179
			StringSwitchCase [] stringCases = new StringSwitchCase[this.caseCount]; // may have to shrink later if multiple strings hash to same code.
181
			BranchLabel[] sourceCaseLabels = new BranchLabel[this.caseCount];
180
			BranchLabel[] sourceCaseLabels = new BranchLabel[this.caseCount];
Lines 242-248 Link Here
242
					codeStream.ifne(stringCases[i].label);
241
					codeStream.ifne(stringCases[i].label);
243
				}
242
				}
244
				codeStream.goto_(defaultBranchLabel);
243
				codeStream.goto_(defaultBranchLabel);
245
			} else if (valueRequired) {
244
			} else {
246
				codeStream.pop();
245
				codeStream.pop();
247
			}
246
			}
248
247
Lines 474-479 Link Here
474
					expressionType = null; // fault-tolerance: ignore type mismatch from constants from hereon
473
					expressionType = null; // fault-tolerance: ignore type mismatch from constants from hereon
475
				}
474
				}
476
			}
475
			}
476
			if (isStringSwitch) {
477
				// the secret variable should be created before iterating over the switch's statements that could
478
				// create more locals. This must be done to prevent overlapping of locals
479
				// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=356002
480
				this.dispatchStringCopy  = new LocalVariableBinding(SecretStringVariableName, upperScope.getJavaLangString(), ClassFileConstants.AccDefault, false);
481
				upperScope.addLocalVariable(this.dispatchStringCopy);
482
				this.dispatchStringCopy.setConstant(Constant.NotAConstant);
483
				this.dispatchStringCopy.useFlag = LocalVariableBinding.USED;
484
			}
477
			if (this.statements != null) {
485
			if (this.statements != null) {
478
				this.scope = new BlockScope(upperScope);
486
				this.scope = new BlockScope(upperScope);
479
				int length;
487
				int length;
Lines 522-533 Link Here
522
					upperScope.problemReporter().undocumentedEmptyBlock(this.blockStart, this.sourceEnd);
530
					upperScope.problemReporter().undocumentedEmptyBlock(this.blockStart, this.sourceEnd);
523
				}
531
				}
524
			}
532
			}
525
			if (isStringSwitch) {
526
				this.dispatchStringCopy  = new LocalVariableBinding(SecretStringVariableName, upperScope.getJavaLangString(), ClassFileConstants.AccDefault, false);
527
				upperScope.addLocalVariable(this.dispatchStringCopy);
528
				this.dispatchStringCopy.setConstant(Constant.NotAConstant);
529
				this.dispatchStringCopy.useFlag = LocalVariableBinding.USED;
530
			}
531
			// for enum switch, check if all constants are accounted for (if no default)
533
			// for enum switch, check if all constants are accounted for (if no default)
532
			if (isEnumSwitch && this.defaultCase == null
534
			if (isEnumSwitch && this.defaultCase == null
533
					&& upperScope.compilerOptions().getSeverity(CompilerOptions.IncompleteEnumSwitch) != ProblemSeverities.Ignore) {
535
					&& upperScope.compilerOptions().getSeverity(CompilerOptions.IncompleteEnumSwitch) != ProblemSeverities.Ignore) {
(-)src/org/eclipse/jdt/core/tests/compiler/regression/SwitchTest.java (+104 lines)
Lines 30-35 Link Here
30
30
31
static {
31
static {
32
//	TESTS_NUMBERS = new int[] { 22 };
32
//	TESTS_NUMBERS = new int[] { 22 };
33
//	TESTS_NAMES = new String[] { "testFor356002", "testFor356002_2", "testFor356002_3" };
33
}
34
}
34
public SwitchTest(String name) {
35
public SwitchTest(String name) {
35
	super(name);
36
	super(name);
Lines 2029-2034 Link Here
2029
										 "DONE");
2030
										 "DONE");
2030
	}
2031
	}
2031
}
2032
}
2033
public void testFor356002() {
2034
	String errorMsg = 		
2035
			"----------\n" + 
2036
			"1. ERROR in X.java (at line 6)\n" + 
2037
			"	switch (foo()) {\n" + 
2038
			"	        ^^^^^\n" + 
2039
			"Cannot switch on a value of type String for source level below 1.7. Only convertible int values or enum variables are permitted\n" + 
2040
			"----------\n";
2041
	
2042
	String [] sourceFiles = 
2043
		new String[] {
2044
		"X.java",
2045
		"public class X {\n" + 
2046
		"	private static String foo() {\n" + 
2047
		"		return \"\";\n" + 
2048
		"	}\n" + 
2049
		"	public static void main(String[] args) {\n" + 
2050
		"		switch (foo()) {\n" + 
2051
		"			default: {\n" + 
2052
		"				int j = 0;\n" + 
2053
		"				if (j <= 0)\n" + 
2054
		"					System.out.println(\"DONE\");\n" +
2055
		"			}\n" + 
2056
		"			return;\n" + 
2057
		"		}\n" + 
2058
		"	}\n" + 
2059
		"}",
2060
	};
2061
	if (this.complianceLevel < JDKLevelSupportingStringSwitch) {
2062
		this.runNegativeTest(sourceFiles, errorMsg);
2063
	} else {
2064
		this.runConformTest(sourceFiles, "DONE");
2065
	}
2066
}
2067
public void testFor356002_2() {
2068
	String errorMsg = 		
2069
			"----------\n" + 
2070
			"1. ERROR in X.java (at line 3)\n" + 
2071
			"	switch (\"\") {\n" + 
2072
			"	        ^^\n" + 
2073
			"Cannot switch on a value of type String for source level below 1.7. Only convertible int values or enum variables are permitted\n" + 
2074
			"----------\n";
2075
	
2076
	String [] sourceFiles = 
2077
		new String[] {
2078
		"X.java",
2079
		"public class X {\n" + 
2080
		"	public static void main(String[] args) {\n" + 
2081
		"		switch (\"\") {\n" + 
2082
		"			default: {\n" + 
2083
		"				int j = 0;\n" + 
2084
		"				if (j <= 0)\n" + 
2085
		"					System.out.println(\"DONE\");\n" +
2086
		"			}\n" + 
2087
		"			return;\n" + 
2088
		"		}\n" + 
2089
		"	}\n" + 
2090
		"}",
2091
	};
2092
	if (this.complianceLevel < JDKLevelSupportingStringSwitch) {
2093
		this.runNegativeTest(sourceFiles, errorMsg);
2094
	} else {
2095
		this.runConformTest(sourceFiles, "DONE");
2096
	}
2097
}
2098
public void testFor356002_3() {
2099
	String errorMsg =
2100
			"----------\n" + 
2101
			"1. ERROR in X.java (at line 7)\n" + 
2102
			"	switch (foo()) {\n" + 
2103
			"	        ^^^^^\n" + 
2104
			"Cannot switch on a value of type String for source level below 1.7. Only convertible int values or enum variables are permitted\n" + 
2105
			"----------\n";
2106
	
2107
	String [] sourceFiles =
2108
		new String[] {
2109
		"X.java",
2110
		"public class X {\n" + 
2111
		"	private static String foo() {\n" + 
2112
		"		return null;\n" + 
2113
		"	}\n" + 
2114
		"	public static void main(String[] args) {\n" +
2115
		"		try {\n" +
2116
		"			switch (foo()) {\n" + 
2117
		"				default: {\n" + 
2118
		"					int j = 0;\n" + 
2119
		"					if (j <= 0)\n" + 
2120
		"						;\n" +
2121
		"				}\n" + 
2122
		"				return;\n" + 
2123
		"			}\n" + 
2124
		"		} catch(NullPointerException e) {\n" +
2125
		"			System.out.println(\"DONE\");\n" +
2126
		"		}\n" +
2127
		"	}\n" + 
2128
		"}",
2129
	};
2130
	if (this.complianceLevel < JDKLevelSupportingStringSwitch) {
2131
		this.runNegativeTest(sourceFiles, errorMsg);
2132
	} else {
2133
		this.runConformTest(sourceFiles, "DONE");
2134
	}
2135
}
2032
public static Class testClass() {
2136
public static Class testClass() {
2033
	return SwitchTest.class;
2137
	return SwitchTest.class;
2034
}
2138
}

Return to bug 356002