Fri, 24 Apr 2020 03:58:51 +0100
Merge
1 /*
2 * Copyright (c) 2013, 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 8013357
27 * @summary javac should correctly enforce binary comparison rules.
28 */
29 import com.sun.tools.javac.code.Type;
30 import com.sun.tools.javac.code.Type.*;
31 import com.sun.tools.javac.code.Symbol.*;
32 import java.io.*;
33 import java.lang.reflect.Array;
34 import java.util.EnumSet;
36 public class TestComparisons {
38 private int errors = 0;
39 private int testnum = 0;
41 static final File testdir = new File("8013357");
43 private enum CompareType {
44 BYTE_PRIM("byte"),
45 SHORT_PRIM("short"),
46 CHAR_PRIM("char"),
47 INTEGER_PRIM("int"),
48 LONG_PRIM("long"),
49 FLOAT_PRIM("float"),
50 DOUBLE_PRIM("double"),
51 BOOLEAN_PRIM("boolean"),
53 BYTE("Byte"),
54 SHORT("Short"),
55 CHAR("Character"),
56 INTEGER("Integer"),
57 LONG("Long"),
58 FLOAT("Float"),
59 DOUBLE("Double"),
60 BOOLEAN("Boolean"),
62 BYTE_SUPER("List<? super Byte>", true),
63 SHORT_SUPER("List<? super Short>", true),
64 CHAR_SUPER("List<? super Character>", true),
65 INTEGER_SUPER("List<? super Integer>", true),
66 LONG_SUPER("List<? super Long>", true),
67 FLOAT_SUPER("List<? super Float>", true),
68 DOUBLE_SUPER("List<? super Double>", true),
69 BOOLEAN_SUPER("List<? super Boolean>", true),
71 OBJECT("Object"),
72 NUMBER("Number"),
73 STRING("String");
75 public final boolean isList;
76 public final String name;
78 private CompareType(final String name, final boolean isList) {
79 this.isList = isList;
80 this.name = name;
81 }
83 private CompareType(final String name) {
84 this(name, false);
85 }
86 }
88 // The integers here refer to which subsection of JLS 15.21 is in
89 // effect. 0 means no comparison is allowed.
90 private static final int truthtab[][] = {
91 // byte, comparable to itself, any numeric type, or any boxed
92 // numeric type.
93 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
94 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
95 0, 0, 0, 0, 0, 0, 0, 0, // Captures
96 0, 0, 0 // Reference types
97 },
98 // short, comparable to itself, any numeric type, or any boxed
99 // numeric type.
100 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
101 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
102 0, 0, 0, 0, 0, 0, 0, 0, // Captures
103 0, 0, 0 // Reference types
104 },
105 // char, comparable to itself, any numeric type, or any boxed
106 // numeric type.
107 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
108 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
109 0, 0, 0, 0, 0, 0, 0, 0, // Captures
110 0, 0, 0 // Reference types
111 },
112 // int, comparable to itself, any numeric type, or any boxed
113 // numeric type.
114 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
115 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
116 0, 0, 0, 0, 0, 0, 0, 0, // Captures
117 0, 0, 0 // Reference types
118 },
119 // long, comparable to itself, any numeric type, or any boxed
120 // numeric type.
121 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
122 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
123 0, 0, 0, 0, 0, 0, 0, 0, // Captures
124 0, 0, 0 // Reference types
125 },
126 // float, comparable to itself, any numeric type, or any boxed
127 // numeric type.
128 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
129 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
130 0, 0, 0, 0, 0, 0, 0, 0, // Captures
131 0, 0, 0 // Reference types
132 },
133 // double, comparable to itself, any numeric type, or any boxed
134 // numeric type.
135 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
136 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
137 0, 0, 0, 0, 0, 0, 0, 0, // Captures
138 0, 0, 0 // Reference types
139 },
140 // boolean, comparable only to itself and Boolean.
141 { 0, 0, 0, 0, 0, 0, 0, 2, // Primitives
142 0, 0, 0, 0, 0, 0, 0, 2, // Boxed primitives
143 0, 0, 0, 0, 0, 0, 0, 0, // Captures
144 0, 0, 0 // Reference types
145 },
146 // Byte, comparable to itself, Number, Object, any numeric primitive,
147 // and any captures.
148 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
149 3, 0, 0, 0, 0, 0, 0, 0, // Boxed primitives
150 3, 3, 3, 3, 3, 3, 3, 3, // Captures
151 3, 3, 0 // Reference types
152 },
153 // Short, comparable to itself, Number, Object, any numeric primitive,
154 // and any captures.
155 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
156 0, 3, 0, 0, 0, 0, 0, 0, // Boxed primitives
157 3, 3, 3, 3, 3, 3, 3, 3, // Captures
158 3, 3, 0 // Reference types
159 },
160 // Character, comparable to itself, Object, any numeric primitive,
161 // and any captures.
162 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
163 0, 0, 3, 0, 0, 0, 0, 0, // Boxed primitives
164 3, 3, 3, 3, 3, 3, 3, 3, // Captures
165 3, 0, 0 // Reference types
166 },
167 // Int, comparable to itself, Number, Object, any numeric primitive,
168 // and any captures.
169 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
170 0, 0, 0, 3, 0, 0, 0, 0, // Boxed primitives
171 3, 3, 3, 3, 3, 3, 3, 3, // Captures
172 3, 3, 0 // Reference types
173 },
174 // Long, comparable to itself, Number, Object, any numeric primitive,
175 // and any captures.
176 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
177 0, 0, 0, 0, 3, 0, 0, 0, // Boxed primitives
178 3, 3, 3, 3, 3, 3, 3, 3, // Captures
179 3, 3, 0 // Reference types
180 },
181 // Float, comparable to itself, Number, Object, any numeric primitive,
182 // and any captures.
183 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
184 0, 0, 0, 0, 0, 3, 0, 0, // Boxed primitives
185 3, 3, 3, 3, 3, 3, 3, 3, // Captures
186 3, 3, 0 // Reference types
187 },
188 // Double, comparable to itself, Number, Object, any numeric primitive,
189 // and any captures.
190 { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
191 0, 0, 0, 0, 0, 0, 3, 0, // Boxed primitives
192 3, 3, 3, 3, 3, 3, 3, 3, // Captures
193 3, 3, 0 // Reference types
194 },
195 // Boolean, to itself, any capture, Object, and boolean.
196 { 0, 0, 0, 0, 0, 0, 0, 2, // Primitives
197 0, 0, 0, 0, 0, 0, 0, 2, // Boxed primitives
198 3, 3, 3, 3, 3, 3, 3, 3, // Captures
199 3, 0, 0 // Reference types
200 },
201 // Byte supertype wildcard, comparable to any reference type.
202 // and any captures.
203 { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
204 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
205 3, 3, 3, 3, 3, 3, 3, 3, // Captures
206 3, 3, 3 // Reference types
207 },
208 // Short supertype wildcard, comparable to any reference type.
209 // and any captures.
210 { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
211 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
212 3, 3, 3, 3, 3, 3, 3, 3, // Captures
213 3, 3, 3 // Reference types
214 },
215 // Character supertype wildcard, comparable to any reference type.
216 // and any captures.
217 { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
218 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
219 3, 3, 3, 3, 3, 3, 3, 3, // Captures
220 3, 3, 3 // Reference types
221 },
222 // Integer supertype wildcard, comparable to any reference type.
223 // and any captures.
224 { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
225 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
226 3, 3, 3, 3, 3, 3, 3, 3, // Captures
227 3, 3, 3 // Reference types
228 },
229 // Long supertype wildcard, comparable to any reference type.
230 // and any captures.
231 { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
232 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
233 3, 3, 3, 3, 3, 3, 3, 3, // Captures
234 3, 3, 3 // Reference types
235 },
236 // Float supertype wildcard, comparable to any reference type.
237 // and any captures.
238 { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
239 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
240 3, 3, 3, 3, 3, 3, 3, 3, // Captures
241 3, 3, 3 // Reference types
242 },
243 // Double supertype wildcard, comparable to any reference type.
244 // and any captures.
245 { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
246 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
247 3, 3, 3, 3, 3, 3, 3, 3, // Captures
248 3, 3, 3 // Reference types
249 },
250 // Boolean supertype wildcard, comparable to any reference type.
251 // and any captures.
252 { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
253 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
254 3, 3, 3, 3, 3, 3, 3, 3, // Captures
255 3, 3, 3 // Reference types
256 },
257 // Object, comparable to any reference type.
258 // and any captures.
259 { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
260 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
261 3, 3, 3, 3, 3, 3, 3, 3, // Captures
262 3, 3, 3 // Reference types
263 },
264 // Number, comparable to Object, any of its subclasses.
265 // and any captures.
266 { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
267 3, 3, 0, 3, 3, 3, 3, 0, // Boxed primitives
268 3, 3, 3, 3, 3, 3, 3, 3, // Captures
269 3, 3, 0 // Reference types
270 },
271 // String supertype wildcard, comparable to any reference type.
272 // and any captures.
273 { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
274 0, 0, 0, 0, 0, 0, 0, 0, // Boxed primitives
275 3, 3, 3, 3, 3, 3, 3, 3, // Captures
276 3, 0, 3 // Reference types
277 }
278 };
280 private void assert_compile_fail(final File file, final String body) {
281 final String filename = file.getPath();
282 final String[] args = { filename };
283 final StringWriter sw = new StringWriter();
284 final PrintWriter pw = new PrintWriter(sw);
285 final int rc = com.sun.tools.javac.Main.compile(args, pw);
286 pw.close();
287 if (rc == 0) {
288 System.err.println("Compilation of " + file.getName() +
289 " didn't fail as expected.\nFile:\n" +
290 body + "\nOutput:\n" + sw.toString());
291 errors++;
292 }
293 }
295 private void assert_compile_succeed(final File file, final String body) {
296 final String filename = file.getPath();
297 final String[] args = { filename };
298 final StringWriter sw = new StringWriter();
299 final PrintWriter pw = new PrintWriter(sw);
300 final int rc = com.sun.tools.javac.Main.compile(args, pw);
301 pw.close();
302 if (rc != 0) {
303 System.err.println("Compilation of " + file.getName() +
304 " didn't succeed as expected.\nFile:\n" +
305 body + "\nOutput:\n" +
306 sw.toString());
307 errors++;
308 }
309 }
311 private String makeBody(final int num,
312 final CompareType left,
313 final CompareType right) {
314 return "import java.util.List;\n" +
315 "public class Test" + num + " {\n" +
316 " public boolean test(" + left.name +
317 " left, " + right.name + " right) {\n" +
318 " return left" + (left.isList ? ".get(0)" : "") +
319 " == right" + (right.isList ? ".get(0)" : "") + ";\n" +
320 " }\n" +
321 "}\n";
322 }
324 private File writeFile(final String filename,
325 final String body)
326 throws IOException {
327 final File f = new File(testdir, filename);
328 f.getParentFile().mkdirs();
329 final FileWriter out = new FileWriter(f);
330 out.write(body);
331 out.close();
332 return f;
333 }
335 private void test(final CompareType left, final CompareType right)
336 throws IOException {
337 final int num = testnum++;
338 final String filename = "Test" + num + ".java";
339 final String body = makeBody(num, left, right);
340 final File file = writeFile(filename, body);
341 if (truthtab[left.ordinal()][right.ordinal()] != 0)
342 assert_compile_succeed(file, body);
343 else
344 assert_compile_fail(file, body);
345 }
347 void run() throws Exception {
348 testdir.mkdir();
350 for(CompareType left : CompareType.values())
351 for(CompareType right : CompareType.values())
352 test(left, right);
354 if (errors != 0)
355 throw new Exception("ObjectZeroCompare test failed with " +
356 errors + " errors.");
357 }
359 public static void main(String... args) throws Exception {
360 new TestComparisons().run();
361 }
362 }