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