1 /*
2  * Copyright (c) 2013, 2018, 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 package org.graalvm.compiler.nodes.test;
26 
27 import jdk.vm.ci.meta.JavaKind;
28 
29 import org.junit.Assert;
30 import org.junit.Test;
31 
32 import org.graalvm.compiler.core.common.type.ObjectStamp;
33 import org.graalvm.compiler.core.common.type.Stamp;
34 import org.graalvm.compiler.core.common.type.StampFactory;
35 import org.graalvm.compiler.core.common.type.TypeReference;
36 import org.graalvm.compiler.nodes.type.StampTool;
37 
38 public class ObjectStampJoinTest extends AbstractObjectStampTest {
39 
40     // class A
41     // class B extends A
42     // class C extends B implements I
43     // class D extends A
44     // abstract class E extends A
45     // interface I
46 
47     @Test
testJoin0()48     public void testJoin0() {
49         Stamp a = StampFactory.object(getType(A.class));
50         Stamp b = StampFactory.object(getType(B.class));
51         Assert.assertEquals(b, join(a, b));
52     }
53 
54     @Test
testJoin1()55     public void testJoin1() {
56         Stamp aNonNull = StampFactory.objectNonNull(getType(A.class));
57         Stamp b = StampFactory.object(getType(B.class));
58         Stamp bNonNull = StampFactory.objectNonNull(getType(B.class));
59         Assert.assertEquals(bNonNull, join(aNonNull, b));
60     }
61 
62     @Test
testJoin2()63     public void testJoin2() {
64         Stamp aExact = StampFactory.objectNonNull(getType(A.class).asExactReference());
65         Stamp b = StampFactory.object(getType(B.class));
66         Assert.assertEquals(StampFactory.empty(JavaKind.Object), join(aExact, b));
67     }
68 
69     @Test
testJoin3()70     public void testJoin3() {
71         Stamp d = StampFactory.object(getType(D.class));
72         Stamp c = StampFactory.object(getType(C.class));
73         Assert.assertTrue(StampTool.isPointerAlwaysNull(join(c, d)));
74     }
75 
76     @Test
testJoin4()77     public void testJoin4() {
78         Stamp dExactNonNull = StampFactory.objectNonNull(getType(D.class));
79         Stamp c = StampFactory.object(getType(C.class));
80         Assert.assertEquals(StampFactory.empty(JavaKind.Object), join(c, dExactNonNull));
81     }
82 
83     @Test
testJoin5()84     public void testJoin5() {
85         Stamp dExact = StampFactory.object(getType(D.class).asExactReference());
86         Stamp c = StampFactory.object(getType(C.class));
87         Stamp join = join(c, dExact);
88         Assert.assertTrue(StampTool.isPointerAlwaysNull(join));
89         Assert.assertNull(StampTool.typeReferenceOrNull(join));
90         Assert.assertFalse(StampTool.isExactType(join));
91     }
92 
93     @Test
testJoin6()94     public void testJoin6() {
95         Stamp dExactNonNull = StampFactory.objectNonNull(getType(D.class).asExactReference());
96         Stamp alwaysNull = StampFactory.alwaysNull();
97         Stamp join = join(alwaysNull, dExactNonNull);
98         Assert.assertFalse(join.hasValues());
99         Assert.assertFalse(StampTool.isPointerAlwaysNull(join));
100     }
101 
102     @Test
testJoin7()103     public void testJoin7() {
104         Stamp aExact = StampFactory.object(getType(A.class).asExactReference());
105         Stamp e = StampFactory.object(getType(E.class));
106         Stamp join = join(aExact, e);
107         Assert.assertTrue(StampTool.isPointerAlwaysNull(join));
108         Assert.assertNull(StampTool.typeReferenceOrNull(join));
109         Assert.assertFalse(StampTool.isExactType(join));
110     }
111 
112     @Test
testJoin8()113     public void testJoin8() {
114         Stamp bExact = StampFactory.objectNonNull(getType(B.class).asExactReference());
115         Stamp dExact = StampFactory.object(getType(D.class).asExactReference());
116         Stamp join = join(bExact, dExact);
117         Assert.assertFalse(join.hasValues());
118     }
119 
120     @Test
testJoin9()121     public void testJoin9() {
122         Stamp bExact = StampFactory.object(getType(B.class).asExactReference());
123         Stamp dExact = StampFactory.object(getType(D.class).asExactReference());
124         Stamp join = join(bExact, dExact);
125         Assert.assertTrue(StampTool.isPointerAlwaysNull(join));
126         Assert.assertNull(StampTool.typeReferenceOrNull(join));
127         Assert.assertNull(StampTool.typeReferenceOrNull(join));
128     }
129 
130     @Test
testJoinInterfaceSimple()131     public void testJoinInterfaceSimple() {
132         // Tests joining of interface
133         testJoinInterface(A.class, B.class, I.class);
134     }
135 
136     @Test
testJoinInterfaceArray()137     public void testJoinInterfaceArray() {
138         // Tests joining of arrays interface
139         testJoinInterface(A[].class, B[].class, I[].class);
140     }
141 
142     @Test
testJoinInterfaceMultiArray()143     public void testJoinInterfaceMultiArray() {
144         // Tests joining of multidimensional arrays of interface
145         testJoinInterface(A[][].class, B[][].class, I[][].class);
146     }
147 
testJoinInterface(Class<?> typeA, Class<?> typeB, Class<?> typeI)148     private void testJoinInterface(Class<?> typeA, Class<?> typeB, Class<?> typeI) {
149         testJoinInterface0(typeA, typeI);
150         testJoinInterface1(typeA, typeI);
151         testJoinInterface2(typeB, typeI);
152         testJoinInterface3(typeB, typeI);
153     }
154 
testJoinInterface0(Class<?> typeA, Class<?> typeI)155     private void testJoinInterface0(Class<?> typeA, Class<?> typeI) {
156         Stamp a = StampFactory.object(getType(typeA));
157         Stamp i = StampFactory.object(getType(typeI));
158         Assert.assertNotSame(StampFactory.empty(JavaKind.Object), join(a, i));
159     }
160 
testJoinInterface1(Class<?> typeA, Class<?> typeI)161     private void testJoinInterface1(Class<?> typeA, Class<?> typeI) {
162         Stamp aNonNull = StampFactory.objectNonNull(getType(typeA));
163         Stamp i = StampFactory.object(getType(typeI));
164         Stamp join = join(aNonNull, i);
165         Assert.assertTrue(join instanceof ObjectStamp);
166         Assert.assertTrue(((ObjectStamp) join).nonNull());
167     }
168 
testJoinInterface2(Class<?> typeB, Class<?> typeI)169     private void testJoinInterface2(Class<?> typeB, Class<?> typeI) {
170         Stamp bExact = StampFactory.objectNonNull(getType(typeB).asExactReference());
171         Stamp i = StampFactory.object(getType(typeI));
172         Stamp join = join(i, bExact);
173         Assert.assertEquals(StampFactory.empty(JavaKind.Object), join);
174     }
175 
testJoinInterface3(Class<?> typeB, Class<?> typeI)176     private void testJoinInterface3(Class<?> typeB, Class<?> typeI) {
177         Stamp bExact = StampFactory.objectNonNull(getType(typeB).asExactReference());
178         // Create non-trusted reference.
179         Stamp i = StampFactory.object(TypeReference.createWithoutAssumptions(getType(typeI).getType()));
180         Stamp join = join(i, bExact);
181         Assert.assertEquals(bExact, join);
182     }
183 
184 }
185