1 /*
2  * Copyright (c) 2010, 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 7006109
27  * @summary Add test library to simplify the task of writing automated type-system tests
28  * @author mcimadamore
29  * @library /tools/lib/types
30  * @modules jdk.compiler/com.sun.tools.javac.code
31  *          jdk.compiler/com.sun.tools.javac.comp
32  *          jdk.compiler/com.sun.tools.javac.file
33  *          jdk.compiler/com.sun.tools.javac.util
34  *          jdk.compiler/com.sun.tools.javac.main
35  *          jdk.compiler/com.sun.tools.javac.tree
36  * @build TypeHarness
37  * @run main CastTest
38  */
39 
40 import com.sun.tools.javac.code.Type;
41 import java.lang.reflect.Array;
42 
43 import static com.sun.tools.javac.code.Flags.*;
44 
45 /**
46  * Check invariants in cast conversion involving primitive types and arrays
47  */
48 public class CastTest extends TypeHarness {
49 
50     Type[] types_no_boxing;
51     Type[] types_boxing;
52 
53     static final boolean T = true;
54     static final boolean F = false;
55 
56     boolean[][] cast_result_no_boxing = {
57                 //byte, short, int, long, float, double, char, bool, C, +C, I, T, byte[], short[], int[], long[], float[], double[], char[], bool[], C[], +C[], I[], T[]
58     /*byte*/    { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
59     /*short*/   { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
60     /*int*/     { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
61     /*long*/    { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
62     /*float*/   { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
63     /*double*/  { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
64     /*char*/    { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
65     /*bool*/    { F   , F    , F  , F   , F    , F     , F   , T   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
66     /*C*/       { F   , F    , F  , F   , F    , F     , F   , F   , T, F , T, T, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
67     /*+C*/      { F   , F    , F  , F   , F    , F     , F   , F   , F, T , F, T, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
68     /*I*/       { F   , F    , F  , F   , F    , F     , F   , F   , T, F , T, T, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
69     /*T*/       { T   , T    , T  , T   , T    , T     , T   , T   , T, T , T, T, T     , T      , T    , T     , T      , T       , T     , T     , T  , T   , T  , T },
70     /*byte[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, T     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
71     /*short[]*/ { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , T      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
72     /*int[]*/   { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , T    , F     , F      , F       , F     , F     , F  , F   , F  , F },
73     /*long[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , T     , F      , F       , F     , F     , F  , F   , F  , F },
74     /*float[]*/ { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , T      , F       , F     , F     , F  , F   , F  , F },
75     /*double[]*/{ F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , T       , F     , F     , F  , F   , F  , F },
76     /*char[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , T     , F     , F  , F   , F  , F },
77     /*bool[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , T     , F  , F   , F  , F },
78     /*C[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , T  , F   , T  , T },
79     /*+C[]*/    { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , F  , T   , F  , T },
80     /*I[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , T  , F   , T  , T },
81     /*T[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , T  , T   , T  , T }};
82 
83     boolean[][] cast_result_boxing = {
84                    //byte, short, int, long, float, double, char, bool, Byte, Short, Integer, Long, Float, Double, Character, Boolean, Object
85     /*byte*/       { T   , T    , T  , T   , T    , T     , T   , F   , T   , F    , F      , F   , F    , F     , F        , F ,      T },
86     /*short*/      { T   , T    , T  , T   , T    , T     , T   , F   , F   , T    , F      , F   , F    , F     , F        , F ,      T  },
87     /*int*/        { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , T      , F   , F    , F     , F        , F ,      T  },
88     /*long*/       { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , T   , F    , F     , F        , F ,      T  },
89     /*float*/      { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , T    , F     , F        , F ,      T  },
90     /*double*/     { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , T     , F        , F ,      T  },
91     /*char*/       { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , F     , T        , F ,      T  },
92     /*bool*/       { F   , F    , F  , F   , F    , F     , F   , T   , F   , F    , F      , F   , F    , F     , F        , T ,      T  },
93     /*Byte*/       { T   , T    , T  , T   , T    , T     , F   , F   , T   , F    , F      , F   , F    , F     , F        , F ,      T  },
94     /*Short*/      { F   , T    , T  , T   , T    , T     , F   , F   , F   , T    , F      , F   , F    , F     , F        , F ,      T  },
95     /*Integer*/    { F   , F    , T  , T   , T    , T     , F   , F   , F   , F    , T      , F   , F    , F     , F        , F ,      T  },
96     /*Long*/       { F   , F    , F  , T   , T    , T     , F   , F   , F   , F    , F      , T   , F    , F     , F        , F ,      T  },
97     /*Float*/      { F   , F    , F  , F   , T    , T     , F   , F   , F   , F    , F      , F   , T    , F     , F        , F ,      T  },
98     /*Double*/     { F   , F    , F  , F   , F    , T     , F   , F   , F   , F    , F      , F   , F    , T     , F        , F ,      T  },
99     /*Character*/  { F   , F    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , F     , T        , F ,      T  },
100     /*Boolean*/    { F   , F    , F  , F   , F    , F     , F   , T   , F   , F    , F      , F   , F    , F     , F        , T ,      T  },
101     /*Object*/     { T   , T    , T  , T   , T    , T     , T   , T   , T   , T    , T      , T   , T    , T     , T        , T ,      T  }};
CastTest()102     CastTest() {
103         Type[] primitiveTypes = {
104             predef.byteType,
105             predef.shortType,
106             predef.intType,
107             predef.longType,
108             predef.floatType,
109             predef.doubleType,
110             predef.charType,
111             predef.booleanType };
112 
113         Type[] boxedTypes = new Type[primitiveTypes.length + 1];
114         for (int i = 0 ; i < primitiveTypes.length ; i++) {
115             boxedTypes[i] = box(primitiveTypes[i]);
116         }
117 
118         boxedTypes[primitiveTypes.length] = predef.objectType;
119 
120         types_boxing = join(Type.class, primitiveTypes, boxedTypes);
121 
122         Type[] referenceTypes = {
123             fac.Class(),
124             fac.Class(FINAL),
125             fac.Interface(),
126             fac.TypeVariable() };
127 
128         Type[] arrayTypes = new Type[primitiveTypes.length + referenceTypes.length];
129         int idx = 0;
130         for (Type t : join(Type.class, primitiveTypes, referenceTypes)) {
131             arrayTypes[idx++] = fac.Array(t);
132         }
133 
134         types_no_boxing = join(Type.class, primitiveTypes, referenceTypes, arrayTypes);
135     }
136 
test(Type[] all_types, boolean[][] cast_result)137     void test(Type[] all_types, boolean[][] cast_result) {
138         for (int i = 0; i < all_types.length ; i++) {
139             for (int j = 0; j < all_types.length ; j++) {
140                 assertCastable(all_types[i], all_types[j], cast_result[i][j]);
141             }
142         }
143     }
144 
runTests()145     void runTests() {
146         test(types_no_boxing, cast_result_no_boxing);
147         test(types_boxing, cast_result_boxing);
148     }
149 
150     @SuppressWarnings("unchecked")
join(Class<T> type, T[]... args)151     <T> T[] join(Class<T> type, T[]... args) {
152         int totalLength = 0;
153         for (T[] arr : args) {
154             totalLength += arr.length;
155         }
156         T[] new_arr = (T[])Array.newInstance(type, totalLength);
157         int idx = 0;
158         for (T[] arr : args) {
159             System.arraycopy(arr, 0, new_arr, idx, arr.length);
160             idx += arr.length;
161         }
162         return new_arr;
163     }
164 
main(String[] args)165     public static void main(String[] args) {
166         new CastTest().runTests();
167     }
168 }
169