Mon, 17 Oct 2011 12:57:36 +0100
7093325: Redundant entry in bytecode exception table
Summary: Inlining of finalizers does not update gaps list accordingly
Reviewed-by: jjg
1 /*
2 * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
24 /*
25 * @test
26 * @bug 6827009 7071246
27 * @summary Positive tests for strings in switch.
28 * @author Joseph D. Darcy
29 */
31 public class StringSwitches {
33 public static void main(String... args) {
34 int failures = 0;
36 failures += testPileup();
37 failures += testSwitchingTwoWays();
38 failures += testNamedBreak();
39 failures += testExtraParens();
41 if (failures > 0) {
42 throw new RuntimeException();
43 }
44 }
46 /*
47 * A zero length string and all strings consisting only of the
48 * zero character \u0000 have a hash code of zero. This method
49 * maps such strings to the number of times \u0000 appears for 0
50 * through 6 occurrences.
51 */
52 private static int zeroHashes(String s) {
53 int result = Integer.MAX_VALUE;
54 switch(s) {
55 case "":
56 return 0;
58 case "\u0000":
59 result = 1; break;
61 case "\u0000\u0000":
62 return 2;
64 case "\u0000\u0000\u0000":
65 result = 3; break;
67 case "\u0000\u0000\u0000\u0000":
68 return 4;
70 case "\u0000\u0000\u0000\u0000\u0000":
71 result = 5; break;
73 case "\u0000\u0000\u0000\u0000\u0000\u0000":
74 return 6;
76 default:
77 result = -1;
78 }
79 return result;
80 }
82 private static int testPileup() {
83 int failures = 0;
84 String zero = "";
85 for(int i = 0; i <= 6; i++, zero += "\u0000") {
86 int result = zeroHashes(zero);
87 if (result != i) {
88 failures++;
89 System.err.printf("For string \"%s\" unexpectedly got %d instead of %d%n.",
90 zero, result, i);
91 }
92 }
94 if (zeroHashes("foo") != -1) {
95 failures++;
96 System.err.println("Failed to get -1 for input string.");
97 }
99 return failures;
100 }
102 /**
103 * Verify that a switch on an enum and a switch with the same
104 * structure on the string name of an enum compute equivalent
105 * values.
106 */
107 private static int testSwitchingTwoWays() {
108 int failures = 0;
110 for(MetaSynVar msv : MetaSynVar.values()) {
111 int enumResult = enumSwitch(msv);
112 int stringResult = stringSwitch(msv.name());
114 if (enumResult != stringResult) {
115 failures++;
116 System.err.printf("One value %s, computed 0x%x with the enum switch " +
117 "and 0x%x with the string one.%n",
118 msv, enumResult, stringResult);
119 }
120 }
122 return failures;
123 }
125 private static enum MetaSynVar {
126 FOO,
127 BAR,
128 BAZ,
129 QUX,
130 QUUX,
131 QUUUX,
132 MUMBLE,
133 FOOBAR;
134 }
136 private static int enumSwitch(MetaSynVar msv) {
137 int result = 0;
138 switch(msv) {
139 case FOO:
140 result |= (1<<0);
141 // fallthrough:
143 case BAR:
144 case BAZ:
145 result |= (1<<1);
146 break;
148 default:
149 switch(msv) {
150 case QUX:
151 result |= (1<<2);
152 break;
154 case QUUX:
155 result |= (1<<3);
157 default:
158 result |= (1<<4);
159 }
160 result |= (1<<5);
161 break;
163 case MUMBLE:
164 result |= (1<<6);
165 return result;
167 case FOOBAR:
168 result |= (1<<7);
169 break;
170 }
171 result |= (1<<8);
172 return result;
173 }
175 private static int stringSwitch(String msvName) {
176 int result = 0;
177 switch(msvName) {
178 case "FOO":
179 result |= (1<<0);
180 // fallthrough:
182 case "BAR":
183 case "BAZ":
184 result |= (1<<1);
185 break;
187 default:
188 switch(msvName) {
189 case "QUX":
190 result |= (1<<2);
191 break;
193 case "QUUX":
194 result |= (1<<3);
196 default:
197 result |= (1<<4);
198 }
199 result |= (1<<5);
200 break;
202 case "MUMBLE":
203 result |= (1<<6);
204 return result;
206 case "FOOBAR":
207 result |= (1<<7);
208 break;
209 }
210 result |= (1<<8);
211 return result;
212 }
214 private static int testNamedBreak() {
215 int failures = 0;
216 String[] testStrings = {"a", "b", "c", "d", "e"};
217 int[] testExpected = { 0b101011, 0b101, 0b100001, 0b101000, 0b10000};
219 for(int i = 0; i < testStrings.length; i++) {
220 int expected = testExpected[i];
221 int result = namedBreak(testStrings[i]);
223 if (result != expected) {
224 failures++;
226 System.err.printf("On input %s, got %d instead of %d.%n",
227 testStrings[i], result, expected);
228 }
229 }
231 return failures;
232 }
234 private static int namedBreak(String s) {
235 int result = 0;
236 outer: switch(s) {
237 case "a":
238 case "b":
239 case "c":
240 result |= (1<<0);
241 inner: switch(s + s) {
242 case "aa":
243 result |= (1<<1);
244 break inner;
246 case "cc":
247 break outer;
249 default:
250 result |= (1<<2);
251 return result;
252 }
254 case "d":
255 result |= (1<<3);
256 break outer;
258 default:
259 return result |= (1<<4);
260 }
261 result |= (1<<5);
262 return result;
263 }
265 private static int testExtraParens() {
266 int failures = 1;
267 String s = "first";
269 switch(s) {
270 case (("first")):
271 failures = 0;
272 break;
273 case ("second"):
274 throw new RuntimeException("Should not be reached.");
275 }
277 return failures;
278 }
279 }