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