1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test/tools/javac/types/TestComparisons.java Wed Apr 27 01:34:52 2016 +0800 1.3 @@ -0,0 +1,362 @@ 1.4 +/* 1.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + */ 1.26 + 1.27 +/* 1.28 + * @test 1.29 + * @bug 8013357 1.30 + * @summary javac should correctly enforce binary comparison rules. 1.31 + */ 1.32 +import com.sun.tools.javac.code.Type; 1.33 +import com.sun.tools.javac.code.Type.*; 1.34 +import com.sun.tools.javac.code.Symbol.*; 1.35 +import java.io.*; 1.36 +import java.lang.reflect.Array; 1.37 +import java.util.EnumSet; 1.38 + 1.39 +public class TestComparisons { 1.40 + 1.41 + private int errors = 0; 1.42 + private int testnum = 0; 1.43 + 1.44 + static final File testdir = new File("8013357"); 1.45 + 1.46 + private enum CompareType { 1.47 + BYTE_PRIM("byte"), 1.48 + SHORT_PRIM("short"), 1.49 + CHAR_PRIM("char"), 1.50 + INTEGER_PRIM("int"), 1.51 + LONG_PRIM("long"), 1.52 + FLOAT_PRIM("float"), 1.53 + DOUBLE_PRIM("double"), 1.54 + BOOLEAN_PRIM("boolean"), 1.55 + 1.56 + BYTE("Byte"), 1.57 + SHORT("Short"), 1.58 + CHAR("Character"), 1.59 + INTEGER("Integer"), 1.60 + LONG("Long"), 1.61 + FLOAT("Float"), 1.62 + DOUBLE("Double"), 1.63 + BOOLEAN("Boolean"), 1.64 + 1.65 + BYTE_SUPER("List<? super Byte>", true), 1.66 + SHORT_SUPER("List<? super Short>", true), 1.67 + CHAR_SUPER("List<? super Character>", true), 1.68 + INTEGER_SUPER("List<? super Integer>", true), 1.69 + LONG_SUPER("List<? super Long>", true), 1.70 + FLOAT_SUPER("List<? super Float>", true), 1.71 + DOUBLE_SUPER("List<? super Double>", true), 1.72 + BOOLEAN_SUPER("List<? super Boolean>", true), 1.73 + 1.74 + OBJECT("Object"), 1.75 + NUMBER("Number"), 1.76 + STRING("String"); 1.77 + 1.78 + public final boolean isList; 1.79 + public final String name; 1.80 + 1.81 + private CompareType(final String name, final boolean isList) { 1.82 + this.isList = isList; 1.83 + this.name = name; 1.84 + } 1.85 + 1.86 + private CompareType(final String name) { 1.87 + this(name, false); 1.88 + } 1.89 + } 1.90 + 1.91 + // The integers here refer to which subsection of JLS 15.21 is in 1.92 + // effect. 0 means no comparison is allowed. 1.93 + private static final int truthtab[][] = { 1.94 + // byte, comparable to itself, any numeric type, or any boxed 1.95 + // numeric type. 1.96 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.97 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 1.98 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 1.99 + 0, 0, 0 // Reference types 1.100 + }, 1.101 + // short, comparable to itself, any numeric type, or any boxed 1.102 + // numeric type. 1.103 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.104 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 1.105 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 1.106 + 0, 0, 0 // Reference types 1.107 + }, 1.108 + // char, comparable to itself, any numeric type, or any boxed 1.109 + // numeric type. 1.110 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.111 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 1.112 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 1.113 + 0, 0, 0 // Reference types 1.114 + }, 1.115 + // int, comparable to itself, any numeric type, or any boxed 1.116 + // numeric type. 1.117 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.118 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 1.119 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 1.120 + 0, 0, 0 // Reference types 1.121 + }, 1.122 + // long, comparable to itself, any numeric type, or any boxed 1.123 + // numeric type. 1.124 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.125 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 1.126 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 1.127 + 0, 0, 0 // Reference types 1.128 + }, 1.129 + // float, comparable to itself, any numeric type, or any boxed 1.130 + // numeric type. 1.131 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.132 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 1.133 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 1.134 + 0, 0, 0 // Reference types 1.135 + }, 1.136 + // double, comparable to itself, any numeric type, or any boxed 1.137 + // numeric type. 1.138 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.139 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 1.140 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 1.141 + 0, 0, 0 // Reference types 1.142 + }, 1.143 + // boolean, comparable only to itself and Boolean. 1.144 + { 0, 0, 0, 0, 0, 0, 0, 2, // Primitives 1.145 + 0, 0, 0, 0, 0, 0, 0, 2, // Boxed primitives 1.146 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 1.147 + 0, 0, 0 // Reference types 1.148 + }, 1.149 + // Byte, comparable to itself, Number, Object, any numeric primitive, 1.150 + // and any captures. 1.151 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.152 + 3, 0, 0, 0, 0, 0, 0, 0, // Boxed primitives 1.153 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.154 + 3, 3, 0 // Reference types 1.155 + }, 1.156 + // Short, comparable to itself, Number, Object, any numeric primitive, 1.157 + // and any captures. 1.158 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.159 + 0, 3, 0, 0, 0, 0, 0, 0, // Boxed primitives 1.160 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.161 + 3, 3, 0 // Reference types 1.162 + }, 1.163 + // Character, comparable to itself, Object, any numeric primitive, 1.164 + // and any captures. 1.165 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.166 + 0, 0, 3, 0, 0, 0, 0, 0, // Boxed primitives 1.167 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.168 + 3, 0, 0 // Reference types 1.169 + }, 1.170 + // Int, comparable to itself, Number, Object, any numeric primitive, 1.171 + // and any captures. 1.172 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.173 + 0, 0, 0, 3, 0, 0, 0, 0, // Boxed primitives 1.174 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.175 + 3, 3, 0 // Reference types 1.176 + }, 1.177 + // Long, comparable to itself, Number, Object, any numeric primitive, 1.178 + // and any captures. 1.179 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.180 + 0, 0, 0, 0, 3, 0, 0, 0, // Boxed primitives 1.181 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.182 + 3, 3, 0 // Reference types 1.183 + }, 1.184 + // Float, comparable to itself, Number, Object, any numeric primitive, 1.185 + // and any captures. 1.186 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.187 + 0, 0, 0, 0, 0, 3, 0, 0, // Boxed primitives 1.188 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.189 + 3, 3, 0 // Reference types 1.190 + }, 1.191 + // Double, comparable to itself, Number, Object, any numeric primitive, 1.192 + // and any captures. 1.193 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 1.194 + 0, 0, 0, 0, 0, 0, 3, 0, // Boxed primitives 1.195 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.196 + 3, 3, 0 // Reference types 1.197 + }, 1.198 + // Boolean, to itself, any capture, Object, and boolean. 1.199 + { 0, 0, 0, 0, 0, 0, 0, 2, // Primitives 1.200 + 0, 0, 0, 0, 0, 0, 0, 2, // Boxed primitives 1.201 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.202 + 3, 0, 0 // Reference types 1.203 + }, 1.204 + // Byte supertype wildcard, comparable to any reference type. 1.205 + // and any captures. 1.206 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 1.207 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 1.208 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.209 + 3, 3, 3 // Reference types 1.210 + }, 1.211 + // Short supertype wildcard, comparable to any reference type. 1.212 + // and any captures. 1.213 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 1.214 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 1.215 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.216 + 3, 3, 3 // Reference types 1.217 + }, 1.218 + // Character supertype wildcard, comparable to any reference type. 1.219 + // and any captures. 1.220 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 1.221 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 1.222 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.223 + 3, 3, 3 // Reference types 1.224 + }, 1.225 + // Integer supertype wildcard, comparable to any reference type. 1.226 + // and any captures. 1.227 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 1.228 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 1.229 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.230 + 3, 3, 3 // Reference types 1.231 + }, 1.232 + // Long supertype wildcard, comparable to any reference type. 1.233 + // and any captures. 1.234 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 1.235 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 1.236 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.237 + 3, 3, 3 // Reference types 1.238 + }, 1.239 + // Float supertype wildcard, comparable to any reference type. 1.240 + // and any captures. 1.241 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 1.242 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 1.243 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.244 + 3, 3, 3 // Reference types 1.245 + }, 1.246 + // Double supertype wildcard, comparable to any reference type. 1.247 + // and any captures. 1.248 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 1.249 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 1.250 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.251 + 3, 3, 3 // Reference types 1.252 + }, 1.253 + // Boolean supertype wildcard, comparable to any reference type. 1.254 + // and any captures. 1.255 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 1.256 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 1.257 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.258 + 3, 3, 3 // Reference types 1.259 + }, 1.260 + // Object, comparable to any reference type. 1.261 + // and any captures. 1.262 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 1.263 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 1.264 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.265 + 3, 3, 3 // Reference types 1.266 + }, 1.267 + // Number, comparable to Object, any of its subclasses. 1.268 + // and any captures. 1.269 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 1.270 + 3, 3, 0, 3, 3, 3, 3, 0, // Boxed primitives 1.271 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.272 + 3, 3, 0 // Reference types 1.273 + }, 1.274 + // String supertype wildcard, comparable to any reference type. 1.275 + // and any captures. 1.276 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 1.277 + 0, 0, 0, 0, 0, 0, 0, 0, // Boxed primitives 1.278 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 1.279 + 3, 0, 3 // Reference types 1.280 + } 1.281 + }; 1.282 + 1.283 + private void assert_compile_fail(final File file, final String body) { 1.284 + final String filename = file.getPath(); 1.285 + final String[] args = { filename }; 1.286 + final StringWriter sw = new StringWriter(); 1.287 + final PrintWriter pw = new PrintWriter(sw); 1.288 + final int rc = com.sun.tools.javac.Main.compile(args, pw); 1.289 + pw.close(); 1.290 + if (rc == 0) { 1.291 + System.err.println("Compilation of " + file.getName() + 1.292 + " didn't fail as expected.\nFile:\n" + 1.293 + body + "\nOutput:\n" + sw.toString()); 1.294 + errors++; 1.295 + } 1.296 + } 1.297 + 1.298 + private void assert_compile_succeed(final File file, final String body) { 1.299 + final String filename = file.getPath(); 1.300 + final String[] args = { filename }; 1.301 + final StringWriter sw = new StringWriter(); 1.302 + final PrintWriter pw = new PrintWriter(sw); 1.303 + final int rc = com.sun.tools.javac.Main.compile(args, pw); 1.304 + pw.close(); 1.305 + if (rc != 0) { 1.306 + System.err.println("Compilation of " + file.getName() + 1.307 + " didn't succeed as expected.\nFile:\n" + 1.308 + body + "\nOutput:\n" + 1.309 + sw.toString()); 1.310 + errors++; 1.311 + } 1.312 + } 1.313 + 1.314 + private String makeBody(final int num, 1.315 + final CompareType left, 1.316 + final CompareType right) { 1.317 + return "import java.util.List;\n" + 1.318 + "public class Test" + num + " {\n" + 1.319 + " public boolean test(" + left.name + 1.320 + " left, " + right.name + " right) {\n" + 1.321 + " return left" + (left.isList ? ".get(0)" : "") + 1.322 + " == right" + (right.isList ? ".get(0)" : "") + ";\n" + 1.323 + " }\n" + 1.324 + "}\n"; 1.325 + } 1.326 + 1.327 + private File writeFile(final String filename, 1.328 + final String body) 1.329 + throws IOException { 1.330 + final File f = new File(testdir, filename); 1.331 + f.getParentFile().mkdirs(); 1.332 + final FileWriter out = new FileWriter(f); 1.333 + out.write(body); 1.334 + out.close(); 1.335 + return f; 1.336 + } 1.337 + 1.338 + private void test(final CompareType left, final CompareType right) 1.339 + throws IOException { 1.340 + final int num = testnum++; 1.341 + final String filename = "Test" + num + ".java"; 1.342 + final String body = makeBody(num, left, right); 1.343 + final File file = writeFile(filename, body); 1.344 + if (truthtab[left.ordinal()][right.ordinal()] != 0) 1.345 + assert_compile_succeed(file, body); 1.346 + else 1.347 + assert_compile_fail(file, body); 1.348 + } 1.349 + 1.350 + void run() throws Exception { 1.351 + testdir.mkdir(); 1.352 + 1.353 + for(CompareType left : CompareType.values()) 1.354 + for(CompareType right : CompareType.values()) 1.355 + test(left, right); 1.356 + 1.357 + if (errors != 0) 1.358 + throw new Exception("ObjectZeroCompare test failed with " + 1.359 + errors + " errors."); 1.360 + } 1.361 + 1.362 + public static void main(String... args) throws Exception { 1.363 + new TestComparisons().run(); 1.364 + } 1.365 +}