test/tools/javac/types/TestComparisons.java

changeset 0
959103a6100f
     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 +}

mercurial