Thu, 27 Jun 2013 17:45:56 -0400
8013357: javac accepts erroneous binary comparison operations
Summary: javac does not report type errors on illegal Object == primitive comparisons
Reviewed-by: abuckley, mcimadamore
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java Thu Jun 27 12:42:47 2013 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Thu Jun 27 17:45:56 2013 -0400 1.3 @@ -1342,6 +1342,26 @@ 1.4 } 1.5 // </editor-fold> 1.6 1.7 + /** 1.8 + * Can t and s be compared for equality? Any primitive == 1.9 + * primitive or primitive == object comparisons here are an error. 1.10 + * Unboxing and correct primitive == primitive comparisons are 1.11 + * already dealt with in Attr.visitBinary. 1.12 + * 1.13 + */ 1.14 + public boolean isEqualityComparable(Type s, Type t, Warner warn) { 1.15 + if (t.isNumeric() && s.isNumeric()) 1.16 + return true; 1.17 + 1.18 + boolean tPrimitive = t.isPrimitive(); 1.19 + boolean sPrimitive = s.isPrimitive(); 1.20 + if (!tPrimitive && !sPrimitive) { 1.21 + return isCastable(s, t, warn) || isCastable(t, s, warn); 1.22 + } else { 1.23 + return false; 1.24 + } 1.25 + } 1.26 + 1.27 // <editor-fold defaultstate="collapsed" desc="isCastable"> 1.28 public boolean isCastable(Type t, Type s) { 1.29 return isCastable(t, s, noWarnings);
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Jun 27 12:42:47 2013 -0700 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Jun 27 17:45:56 2013 -0400 2.3 @@ -3010,6 +3010,8 @@ 2.4 !left.isErroneous() && 2.5 !right.isErroneous()) { 2.6 owntype = operator.type.getReturnType(); 2.7 + // This will figure out when unboxing can happen and 2.8 + // choose the right comparison operator. 2.9 int opc = chk.checkOperator(tree.lhs.pos(), 2.10 (OperatorSymbol)operator, 2.11 tree.getTag(), 2.12 @@ -3037,9 +3039,11 @@ 2.13 } 2.14 2.15 // Check that argument types of a reference ==, != are 2.16 - // castable to each other, (JLS???). 2.17 + // castable to each other, (JLS 15.21). Note: unboxing 2.18 + // comparisons will not have an acmp* opc at this point. 2.19 if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) { 2.20 - if (!types.isCastable(left, right, new Warner(tree.pos()))) { 2.21 + if (!types.isEqualityComparable(left, right, 2.22 + new Warner(tree.pos()))) { 2.23 log.error(tree.pos(), "incomparable.types", left, right); 2.24 } 2.25 }
3.1 --- a/test/tools/javac/lambda/LambdaConv01.java Thu Jun 27 12:42:47 2013 -0700 3.2 +++ b/test/tools/javac/lambda/LambdaConv01.java Thu Jun 27 17:45:56 2013 -0400 3.3 @@ -67,7 +67,7 @@ 3.4 assertTrue(3 == f1.foo()); 3.5 //Covariant returns: 3.6 TU<Number, Integer> f2 = (Integer x) -> x; 3.7 - assertTrue(3 == f2.foo(3)); 3.8 + assertTrue(3 == f2.foo(3).intValue()); 3.9 //Method resolution with boxing: 3.10 int res = LambdaConv01.<Integer,Integer>exec((Integer x) -> x, 3); 3.11 assertTrue(3 == res); 3.12 @@ -86,7 +86,7 @@ 3.13 assertTrue(3 == f1.foo()); 3.14 //Covariant returns: 3.15 TU<Number, Integer> f2 = (Integer x) -> x; 3.16 - assertTrue(3 == f2.foo(3)); 3.17 + assertTrue(3 == f2.foo(3).intValue()); 3.18 //Method resolution with boxing: 3.19 int res = LambdaConv01.<Integer,Integer>exec((Integer x) -> x, 3); 3.20 assertTrue(3 == res); 3.21 @@ -105,7 +105,7 @@ 3.22 assertTrue(3 == f1.foo()); 3.23 //Covariant returns: 3.24 TU<Number, Integer> f2 = (Integer x) -> x; 3.25 - assertTrue(3 == f2.foo(3)); 3.26 + assertTrue(3 == f2.foo(3).intValue()); 3.27 //Method resolution with boxing: 3.28 int res = LambdaConv01.<Integer,Integer>exec((Integer x) -> x, 3); 3.29 assertTrue(3 == res); 3.30 @@ -124,7 +124,7 @@ 3.31 assertTrue(3 == f1.foo()); 3.32 //Covariant returns: 3.33 TU<Number, Integer> f2 = (Integer x) -> x; 3.34 - assertTrue(3 == f2.foo(3)); 3.35 + assertTrue(3 == f2.foo(3).intValue()); 3.36 //Method resolution with boxing: 3.37 int res = LambdaConv01.<Integer,Integer>exec((Integer x) -> x, 3); 3.38 assertTrue(3 == res);
4.1 --- a/test/tools/javac/lambda/LambdaExpr15.java Thu Jun 27 12:42:47 2013 -0700 4.2 +++ b/test/tools/javac/lambda/LambdaExpr15.java Thu Jun 27 17:45:56 2013 -0400 4.3 @@ -48,7 +48,7 @@ 4.4 new Object() { 4.5 String get() { return ""; } 4.6 }; 4.7 - assertTrue(t == 1); 4.8 + assertTrue((Integer)t == 1); 4.9 }; 4.10 ba1.apply(1); 4.11 4.12 @@ -58,7 +58,7 @@ 4.13 String get() { return ""; } 4.14 }; 4.15 new A(); 4.16 - assertTrue(t == 2); 4.17 + assertTrue((Integer)t == 2); 4.18 }; 4.19 ba2.apply(2); 4.20 assertTrue(assertionCount == 2);
5.1 --- a/test/tools/javac/lambda/typeInference/InferenceTest2b.java Thu Jun 27 12:42:47 2013 -0700 5.2 +++ b/test/tools/javac/lambda/typeInference/InferenceTest2b.java Thu Jun 27 17:45:56 2013 -0400 5.3 @@ -64,7 +64,7 @@ 5.4 5.5 void m2(SAM6<? super Integer> s) { 5.6 System.out.println("m2()"); 5.7 - assertTrue(s.m6(1, 2) == 1); 5.8 + assertTrue(s.m6(1, 2).equals(Integer.valueOf(1))); 5.9 } 5.10 5.11 void m3(SAM6<? super Calendar> s) {
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/tools/javac/types/TestComparisons.java Thu Jun 27 17:45:56 2013 -0400 6.3 @@ -0,0 +1,362 @@ 6.4 +/* 6.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.23 + * or visit www.oracle.com if you need additional information or have any 6.24 + * questions. 6.25 + */ 6.26 + 6.27 +/* 6.28 + * @test 6.29 + * @bug 8013357 6.30 + * @summary javac should correctly enforce binary comparison rules. 6.31 + */ 6.32 +import com.sun.tools.javac.code.Type; 6.33 +import com.sun.tools.javac.code.Type.*; 6.34 +import com.sun.tools.javac.code.Symbol.*; 6.35 +import java.io.*; 6.36 +import java.lang.reflect.Array; 6.37 +import java.util.EnumSet; 6.38 + 6.39 +public class TestComparisons { 6.40 + 6.41 + private int errors = 0; 6.42 + private int testnum = 0; 6.43 + 6.44 + static final File testdir = new File("8013357"); 6.45 + 6.46 + private enum CompareType { 6.47 + BYTE_PRIM("byte"), 6.48 + SHORT_PRIM("short"), 6.49 + CHAR_PRIM("char"), 6.50 + INTEGER_PRIM("int"), 6.51 + LONG_PRIM("long"), 6.52 + FLOAT_PRIM("float"), 6.53 + DOUBLE_PRIM("double"), 6.54 + BOOLEAN_PRIM("boolean"), 6.55 + 6.56 + BYTE("Byte"), 6.57 + SHORT("Short"), 6.58 + CHAR("Character"), 6.59 + INTEGER("Integer"), 6.60 + LONG("Long"), 6.61 + FLOAT("Float"), 6.62 + DOUBLE("Double"), 6.63 + BOOLEAN("Boolean"), 6.64 + 6.65 + BYTE_SUPER("List<? super Byte>", true), 6.66 + SHORT_SUPER("List<? super Short>", true), 6.67 + CHAR_SUPER("List<? super Character>", true), 6.68 + INTEGER_SUPER("List<? super Integer>", true), 6.69 + LONG_SUPER("List<? super Long>", true), 6.70 + FLOAT_SUPER("List<? super Float>", true), 6.71 + DOUBLE_SUPER("List<? super Double>", true), 6.72 + BOOLEAN_SUPER("List<? super Boolean>", true), 6.73 + 6.74 + OBJECT("Object"), 6.75 + NUMBER("Number"), 6.76 + STRING("String"); 6.77 + 6.78 + public final boolean isList; 6.79 + public final String name; 6.80 + 6.81 + private CompareType(final String name, final boolean isList) { 6.82 + this.isList = isList; 6.83 + this.name = name; 6.84 + } 6.85 + 6.86 + private CompareType(final String name) { 6.87 + this(name, false); 6.88 + } 6.89 + } 6.90 + 6.91 + // The integers here refer to which subsection of JLS 15.21 is in 6.92 + // effect. 0 means no comparison is allowed. 6.93 + private static final int truthtab[][] = { 6.94 + // byte, comparable to itself, any numeric type, or any boxed 6.95 + // numeric type. 6.96 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.97 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 6.98 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 6.99 + 0, 0, 0 // Reference types 6.100 + }, 6.101 + // short, comparable to itself, any numeric type, or any boxed 6.102 + // numeric type. 6.103 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.104 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 6.105 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 6.106 + 0, 0, 0 // Reference types 6.107 + }, 6.108 + // char, comparable to itself, any numeric type, or any boxed 6.109 + // numeric type. 6.110 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.111 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 6.112 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 6.113 + 0, 0, 0 // Reference types 6.114 + }, 6.115 + // int, comparable to itself, any numeric type, or any boxed 6.116 + // numeric type. 6.117 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.118 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 6.119 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 6.120 + 0, 0, 0 // Reference types 6.121 + }, 6.122 + // long, comparable to itself, any numeric type, or any boxed 6.123 + // numeric type. 6.124 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.125 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 6.126 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 6.127 + 0, 0, 0 // Reference types 6.128 + }, 6.129 + // float, comparable to itself, any numeric type, or any boxed 6.130 + // numeric type. 6.131 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.132 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 6.133 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 6.134 + 0, 0, 0 // Reference types 6.135 + }, 6.136 + // double, comparable to itself, any numeric type, or any boxed 6.137 + // numeric type. 6.138 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.139 + 1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives 6.140 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 6.141 + 0, 0, 0 // Reference types 6.142 + }, 6.143 + // boolean, comparable only to itself and Boolean. 6.144 + { 0, 0, 0, 0, 0, 0, 0, 2, // Primitives 6.145 + 0, 0, 0, 0, 0, 0, 0, 2, // Boxed primitives 6.146 + 0, 0, 0, 0, 0, 0, 0, 0, // Captures 6.147 + 0, 0, 0 // Reference types 6.148 + }, 6.149 + // Byte, comparable to itself, Number, Object, any numeric primitive, 6.150 + // and any captures. 6.151 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.152 + 3, 0, 0, 0, 0, 0, 0, 0, // Boxed primitives 6.153 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.154 + 3, 3, 0 // Reference types 6.155 + }, 6.156 + // Short, comparable to itself, Number, Object, any numeric primitive, 6.157 + // and any captures. 6.158 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.159 + 0, 3, 0, 0, 0, 0, 0, 0, // Boxed primitives 6.160 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.161 + 3, 3, 0 // Reference types 6.162 + }, 6.163 + // Character, comparable to itself, Object, any numeric primitive, 6.164 + // and any captures. 6.165 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.166 + 0, 0, 3, 0, 0, 0, 0, 0, // Boxed primitives 6.167 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.168 + 3, 0, 0 // Reference types 6.169 + }, 6.170 + // Int, comparable to itself, Number, Object, any numeric primitive, 6.171 + // and any captures. 6.172 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.173 + 0, 0, 0, 3, 0, 0, 0, 0, // Boxed primitives 6.174 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.175 + 3, 3, 0 // Reference types 6.176 + }, 6.177 + // Long, comparable to itself, Number, Object, any numeric primitive, 6.178 + // and any captures. 6.179 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.180 + 0, 0, 0, 0, 3, 0, 0, 0, // Boxed primitives 6.181 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.182 + 3, 3, 0 // Reference types 6.183 + }, 6.184 + // Float, comparable to itself, Number, Object, any numeric primitive, 6.185 + // and any captures. 6.186 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.187 + 0, 0, 0, 0, 0, 3, 0, 0, // Boxed primitives 6.188 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.189 + 3, 3, 0 // Reference types 6.190 + }, 6.191 + // Double, comparable to itself, Number, Object, any numeric primitive, 6.192 + // and any captures. 6.193 + { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives 6.194 + 0, 0, 0, 0, 0, 0, 3, 0, // Boxed primitives 6.195 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.196 + 3, 3, 0 // Reference types 6.197 + }, 6.198 + // Boolean, to itself, any capture, Object, and boolean. 6.199 + { 0, 0, 0, 0, 0, 0, 0, 2, // Primitives 6.200 + 0, 0, 0, 0, 0, 0, 0, 2, // Boxed primitives 6.201 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.202 + 3, 0, 0 // Reference types 6.203 + }, 6.204 + // Byte supertype wildcard, comparable to any reference type. 6.205 + // and any captures. 6.206 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 6.207 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 6.208 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.209 + 3, 3, 3 // Reference types 6.210 + }, 6.211 + // Short supertype wildcard, comparable to any reference type. 6.212 + // and any captures. 6.213 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 6.214 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 6.215 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.216 + 3, 3, 3 // Reference types 6.217 + }, 6.218 + // Character supertype wildcard, comparable to any reference type. 6.219 + // and any captures. 6.220 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 6.221 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 6.222 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.223 + 3, 3, 3 // Reference types 6.224 + }, 6.225 + // Integer supertype wildcard, comparable to any reference type. 6.226 + // and any captures. 6.227 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 6.228 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 6.229 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.230 + 3, 3, 3 // Reference types 6.231 + }, 6.232 + // Long supertype wildcard, comparable to any reference type. 6.233 + // and any captures. 6.234 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 6.235 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 6.236 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.237 + 3, 3, 3 // Reference types 6.238 + }, 6.239 + // Float supertype wildcard, comparable to any reference type. 6.240 + // and any captures. 6.241 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 6.242 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 6.243 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.244 + 3, 3, 3 // Reference types 6.245 + }, 6.246 + // Double supertype wildcard, comparable to any reference type. 6.247 + // and any captures. 6.248 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 6.249 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 6.250 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.251 + 3, 3, 3 // Reference types 6.252 + }, 6.253 + // Boolean supertype wildcard, comparable to any reference type. 6.254 + // and any captures. 6.255 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 6.256 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 6.257 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.258 + 3, 3, 3 // Reference types 6.259 + }, 6.260 + // Object, comparable to any reference type. 6.261 + // and any captures. 6.262 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 6.263 + 3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives 6.264 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.265 + 3, 3, 3 // Reference types 6.266 + }, 6.267 + // Number, comparable to Object, any of its subclasses. 6.268 + // and any captures. 6.269 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 6.270 + 3, 3, 0, 3, 3, 3, 3, 0, // Boxed primitives 6.271 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.272 + 3, 3, 0 // Reference types 6.273 + }, 6.274 + // String supertype wildcard, comparable to any reference type. 6.275 + // and any captures. 6.276 + { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives 6.277 + 0, 0, 0, 0, 0, 0, 0, 0, // Boxed primitives 6.278 + 3, 3, 3, 3, 3, 3, 3, 3, // Captures 6.279 + 3, 0, 3 // Reference types 6.280 + } 6.281 + }; 6.282 + 6.283 + private void assert_compile_fail(final File file, final String body) { 6.284 + final String filename = file.getPath(); 6.285 + final String[] args = { filename }; 6.286 + final StringWriter sw = new StringWriter(); 6.287 + final PrintWriter pw = new PrintWriter(sw); 6.288 + final int rc = com.sun.tools.javac.Main.compile(args, pw); 6.289 + pw.close(); 6.290 + if (rc == 0) { 6.291 + System.err.println("Compilation of " + file.getName() + 6.292 + " didn't fail as expected.\nFile:\n" + 6.293 + body + "\nOutput:\n" + sw.toString()); 6.294 + errors++; 6.295 + } 6.296 + } 6.297 + 6.298 + private void assert_compile_succeed(final File file, final String body) { 6.299 + final String filename = file.getPath(); 6.300 + final String[] args = { filename }; 6.301 + final StringWriter sw = new StringWriter(); 6.302 + final PrintWriter pw = new PrintWriter(sw); 6.303 + final int rc = com.sun.tools.javac.Main.compile(args, pw); 6.304 + pw.close(); 6.305 + if (rc != 0) { 6.306 + System.err.println("Compilation of " + file.getName() + 6.307 + " didn't succeed as expected.\nFile:\n" + 6.308 + body + "\nOutput:\n" + 6.309 + sw.toString()); 6.310 + errors++; 6.311 + } 6.312 + } 6.313 + 6.314 + private String makeBody(final int num, 6.315 + final CompareType left, 6.316 + final CompareType right) { 6.317 + return "import java.util.List;\n" + 6.318 + "public class Test" + num + " {\n" + 6.319 + " public boolean test(" + left.name + 6.320 + " left, " + right.name + " right) {\n" + 6.321 + " return left" + (left.isList ? ".get(0)" : "") + 6.322 + " == right" + (right.isList ? ".get(0)" : "") + ";\n" + 6.323 + " }\n" + 6.324 + "}\n"; 6.325 + } 6.326 + 6.327 + private File writeFile(final String filename, 6.328 + final String body) 6.329 + throws IOException { 6.330 + final File f = new File(testdir, filename); 6.331 + f.getParentFile().mkdirs(); 6.332 + final FileWriter out = new FileWriter(f); 6.333 + out.write(body); 6.334 + out.close(); 6.335 + return f; 6.336 + } 6.337 + 6.338 + private void test(final CompareType left, final CompareType right) 6.339 + throws IOException { 6.340 + final int num = testnum++; 6.341 + final String filename = "Test" + num + ".java"; 6.342 + final String body = makeBody(num, left, right); 6.343 + final File file = writeFile(filename, body); 6.344 + if (truthtab[left.ordinal()][right.ordinal()] != 0) 6.345 + assert_compile_succeed(file, body); 6.346 + else 6.347 + assert_compile_fail(file, body); 6.348 + } 6.349 + 6.350 + void run() throws Exception { 6.351 + testdir.mkdir(); 6.352 + 6.353 + for(CompareType left : CompareType.values()) 6.354 + for(CompareType right : CompareType.values()) 6.355 + test(left, right); 6.356 + 6.357 + if (errors != 0) 6.358 + throw new Exception("ObjectZeroCompare test failed with " + 6.359 + errors + " errors."); 6.360 + } 6.361 + 6.362 + public static void main(String... args) throws Exception { 6.363 + new TestComparisons().run(); 6.364 + } 6.365 +}