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