content: /*
   * Copyright (C) 2016 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.
   */
  
  // We make Main extend an unresolved super class. This will lead to an
  // unresolved access to Foo.field, as we won't know if Main can access
  // a package private field.
  public class Main extends MissingSuperClass {
  
    public static void main(String[] args) {
      instanceFieldTest();
      staticFieldTest();
      instanceFieldTest2();
    }
  
    /// CHECK-START: void Main.instanceFieldTest() inliner (before)
    /// CHECK-NOT:    InstanceFieldSet
  
    /// CHECK-START: void Main.instanceFieldTest() inliner (after)
    /// CHECK:        InstanceFieldSet
    /// CHECK:        UnresolvedInstanceFieldGet
  
    // Load store elimination used to remove the InstanceFieldSet, thinking
    // that the UnresolvedInstanceFieldGet was not related. However inlining
    // can put you in a situation where the UnresolvedInstanceFieldGet resolves
    // to the same field as the one in InstanceFieldSet. So the InstanceFieldSet
    // must be preserved.
  
    /// CHECK-START: void Main.instanceFieldTest() load_store_elimination (after)
    /// CHECK:        InstanceFieldSet
    /// CHECK:        UnresolvedInstanceFieldGet
    public static void instanceFieldTest() {
      Foo f = new Foo();
      if (f.iField != 42) {
        throw new Error("Expected 42, got " + f.iField);
      }
    }
  
    /// CHECK-START: void Main.instanceFieldTest2() inliner (before)
    /// CHECK-NOT:    InstanceFieldSet
    /// CHECK-NOT:    InstanceFieldGet
  
    /// CHECK-START: void Main.instanceFieldTest2() inliner (after)
    /// CHECK:        InstanceFieldSet
    /// CHECK:        InstanceFieldGet
    /// CHECK:        UnresolvedInstanceFieldSet
    /// CHECK:        InstanceFieldGet
  
    // Load store elimination will eliminate the first InstanceFieldGet because
    // it simply follows an InstanceFieldSet. It must however not eliminate the second
    // InstanceFieldGet, as the UnresolvedInstanceFieldSet might resolve to the same
    // field.
  
    /// CHECK-START: void Main.instanceFieldTest2() load_store_elimination (after)
    /// CHECK:        InstanceFieldSet
    /// CHECK-NOT:    InstanceFieldGet
    /// CHECK:        UnresolvedInstanceFieldSet
    /// CHECK:        InstanceFieldGet
    public static void instanceFieldTest2() {
      Foo f = new Foo();
      int a = f.$inline$GetInstanceField();
      f.iField = 43;
      a = f.$inline$GetInstanceField();
      if (a != 43) {
        throw new Error("Expected 43, got " + a);
      }
    }
  
    /// CHECK-START: void Main.staticFieldTest() inliner (before)
    /// CHECK-NOT:    StaticFieldSet
  
    /// CHECK-START: void Main.staticFieldTest() inliner (after)
    /// CHECK:        StaticFieldSet
    /// CHECK:        StaticFieldSet
    /// CHECK:        UnresolvedStaticFieldGet
  
    /// CHECK-START: void Main.staticFieldTest() load_store_elimination (after)
    /// CHECK:        StaticFieldSet
    /// CHECK:        StaticFieldSet
    /// CHECK:        UnresolvedStaticFieldGet
    public static void staticFieldTest() {
      // Ensure Foo is initialized.
      Foo f = new Foo();
      f.$inline$StaticSet42();
      f.$inline$StaticSet43();
      if (Foo.sField != 43) {
        throw new Error("Expected 43, got " + Foo.sField);
      }
    }
  }
  
  class Foo {
    // field needs to be package-private to make the access in Main.main
    // unresolved.
    int iField;
    static int sField;
  
    public void $inline$StaticSet42() {
      sField = 42;
    }
  
    public void $inline$StaticSet43() {
      sField = 43;
    }
  
    public int $inline$GetInstanceField() {
      return iField;
    }
  
    // Constructor needs to be public to get it resolved in Main.main
    // and therefore inlined.
    public Foo() {
      iField = 42;
    }
  }
  