content: /*
   * Copyright (C) 2015 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  public class Main {
    public static boolean $inline$classTypeTest(Object o) {
      return ((SubMain)o) == o;
    }
  
    public static boolean $inline$interfaceTypeTest(Object o) {
      return ((Itf)o) == o;
    }
  
    public static SubMain subMain;
    public static Main mainField;
    public static Unrelated unrelatedField;
    public static FinalUnrelated finalUnrelatedField;
  
    /// CHECK-START: boolean Main.classTypeTestNull() register (after)
    /// CHECK-NOT: CheckCast
    public static boolean classTypeTestNull() {
      return $inline$classTypeTest(null);
    }
  
    /// CHECK-START: boolean Main.classTypeTestExactMain() register (after)
    /// CHECK: CheckCast
    public static boolean classTypeTestExactMain() {
      return $inline$classTypeTest(new Main());
    }
  
    /// CHECK-START: boolean Main.classTypeTestExactSubMain() register (after)
    /// CHECK-NOT: CheckCast
    public static boolean classTypeTestExactSubMain() {
      return $inline$classTypeTest(new SubMain());
    }
  
    /// CHECK-START: boolean Main.classTypeTestSubMainOrNull() register (after)
    /// CHECK-NOT: CheckCast
    public static boolean classTypeTestSubMainOrNull() {
      return $inline$classTypeTest(subMain);
    }
  
    /// CHECK-START: boolean Main.classTypeTestMainOrNull() register (after)
    /// CHECK: CheckCast
    public static boolean classTypeTestMainOrNull() {
      return $inline$classTypeTest(mainField);
    }
  
    /// CHECK-START: boolean Main.classTypeTestUnrelated() register (after)
    /// CHECK: CheckCast
    public static boolean classTypeTestUnrelated() {
      return $inline$classTypeTest(unrelatedField);
    }
  
    /// CHECK-START: boolean Main.classTypeTestFinalUnrelated() register (after)
    /// CHECK: CheckCast
    public static boolean classTypeTestFinalUnrelated() {
      return $inline$classTypeTest(finalUnrelatedField);
    }
  
    /// CHECK-START: boolean Main.interfaceTypeTestNull() register (after)
    /// CHECK-NOT: CheckCast
    public static boolean interfaceTypeTestNull() {
      return $inline$interfaceTypeTest(null);
    }
  
    /// CHECK-START: boolean Main.interfaceTypeTestExactMain() register (after)
    /// CHECK: CheckCast
    public static boolean interfaceTypeTestExactMain() {
      return $inline$interfaceTypeTest(new Main());
    }
  
    /// CHECK-START: boolean Main.interfaceTypeTestExactSubMain() register (after)
    /// CHECK-NOT: CheckCast
    public static boolean interfaceTypeTestExactSubMain() {
      return $inline$interfaceTypeTest(new SubMain());
    }
  
    /// CHECK-START: boolean Main.interfaceTypeTestSubMainOrNull() register (after)
    /// CHECK-NOT: CheckCast
    public static boolean interfaceTypeTestSubMainOrNull() {
      return $inline$interfaceTypeTest(subMain);
    }
  
    /// CHECK-START: boolean Main.interfaceTypeTestMainOrNull() register (after)
    /// CHECK: CheckCast
    public static boolean interfaceTypeTestMainOrNull() {
      return $inline$interfaceTypeTest(mainField);
    }
  
    /// CHECK-START: boolean Main.interfaceTypeTestUnrelated() register (after)
    /// CHECK: CheckCast
    public static boolean interfaceTypeTestUnrelated() {
      return $inline$interfaceTypeTest(unrelatedField);
    }
  
    /// CHECK-START: boolean Main.interfaceTypeTestFinalUnrelated() register (after)
    /// CHECK: CheckCast
    public static boolean interfaceTypeTestFinalUnrelated() {
      return $inline$interfaceTypeTest(finalUnrelatedField);
    }
  
    /// CHECK-START: java.lang.String Main.knownTestWithLoadedClass() register (after)
    /// CHECK-NOT: CheckCast
    public static String knownTestWithLoadedClass() {
      return (String)$inline$getString();
    }
  
    /// CHECK-START: Itf Main.knownTestWithUnloadedClass() register (after)
    /// CHECK: CheckCast
    public static Itf knownTestWithUnloadedClass() {
      return (Itf)$inline$getString();
    }
  
    public static Object $inline$getString() {
      return new String();
    }
  
    public static Object $inline$getMain() {
      return new Main();
    }
  
    /// CHECK-START: void Main.nonNullBoundType() register (after)
    /// CHECK-NOT: NullCheck
    public static void nonNullBoundType() {
      Main main = (Main)$inline$getMain();
      main.getClass();
    }
  
    public static void main(String[] args) {
      classTypeTestNull();
      try {
        classTypeTestExactMain();
        throw new Error("ClassCastException expected");
      } catch (ClassCastException e) {}
      classTypeTestExactSubMain();
  
      subMain = null;
      classTypeTestSubMainOrNull();
      subMain = new SubMain();
      classTypeTestSubMainOrNull();
  
      mainField = null;
      classTypeTestMainOrNull();
      mainField = new Main();
      try {
        classTypeTestMainOrNull();
        throw new Error("ClassCastException expected");
      } catch (ClassCastException e) {}
      mainField = new SubMain();
      classTypeTestMainOrNull();
  
      unrelatedField = null;
      classTypeTestUnrelated();
      unrelatedField = new Unrelated();
      try {
        classTypeTestUnrelated();
        throw new Error("ClassCastException expected");
      } catch (ClassCastException e) {}
  
      finalUnrelatedField = null;
      classTypeTestFinalUnrelated();
      finalUnrelatedField = new FinalUnrelated();
      try {
        classTypeTestFinalUnrelated();
        throw new Error("ClassCastException expected");
      } catch (ClassCastException e) {}
  
      interfaceTypeTestNull();
      try {
        interfaceTypeTestExactMain();
        throw new Error("ClassCastException expected");
      } catch (ClassCastException e) {}
      interfaceTypeTestExactSubMain();
  
      subMain = null;
      interfaceTypeTestSubMainOrNull();
      subMain = new SubMain();
      interfaceTypeTestSubMainOrNull();
  
      mainField = null;
      interfaceTypeTestMainOrNull();
      mainField = new Main();
      try {
        interfaceTypeTestMainOrNull();
        throw new Error("ClassCastException expected");
      } catch (ClassCastException e) {}
      mainField = new SubMain();
      interfaceTypeTestMainOrNull();
  
      unrelatedField = null;
      interfaceTypeTestUnrelated();
      unrelatedField = new Unrelated();
      try {
        interfaceTypeTestUnrelated();
        throw new Error("ClassCastException expected");
      } catch (ClassCastException e) {}
  
      finalUnrelatedField = null;
      interfaceTypeTestFinalUnrelated();
      finalUnrelatedField = new FinalUnrelated();
      try {
        interfaceTypeTestFinalUnrelated();
        throw new Error("ClassCastException expected");
      } catch (ClassCastException e) {}
    }
  }
  
  interface Itf {
  }
  
  class SubMain extends Main implements Itf {
  }
  
  class Unrelated {
  }
  
  final class FinalUnrelated {
  }
  