// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.jasmin;

import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestDiagnosticMessages;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.jasmin.JasminBuilder.ClassFileVersion;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class InvalidDebugInfoTests extends TestBase {

  @Parameters(name = "{0}, strict:{1}")
  public static List<Object[]> data() {
    return buildParameters(
        getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build(),
        BooleanUtils.values());
  }

  private final TestParameters parameters;
  private final boolean strict;

  public InvalidDebugInfoTests(TestParameters parameters, boolean strict) {
    this.parameters = parameters;
    this.strict = strict;
  }

  private void optionsModification(InternalOptions options) {
    options.invalidDebugInfoStrict = strict;
    options.testing.forceIRForCfToCfDesugar = true;
  }

  private void assertInvalidTypeMessage(TestDiagnosticMessages diagnostics) {
    assertInvalidInfoMessages(diagnostics, "Attempt to define local of type");
  }

  private void assertUninitializedLocalMessage(TestDiagnosticMessages diagnostics) {
    assertInvalidInfoMessages(diagnostics, "Local refers to uninitialized register");
  }

  private void assertInvalidInfoMessages(TestDiagnosticMessages diagnostics, String message) {
    // The reporting of invalid debug info issues three info items:
    diagnostics.assertOnlyInfos();
    diagnostics.assertInfosMatch(
        ImmutableList.of(
            diagnosticMessage(containsString("Stripped invalid locals information")),
            diagnosticMessage(containsString(message)),
            diagnosticMessage(containsString("sign of using an outdated Java toolchain"))));
  }

  // This is a regression test for invalid live-ranges of locals generated by some old Java
  // compilers. The issue is that a local slot may have been initialized outside the live-scope of
  // the variable and then the subsequent live-scope of the variable extends beyond its actual
  // liveness. In the example below the variable 'y' is initialized outside its range (it is thus
  // associated with the local 'x' (the SSA value is unaffected by the istore). Finally the 'return'
  // forces a read of all supposedly live variables before exiting. Here the attempt to read 'y'
  // will actually be a read of 'x'.
  @Test
  public void testInvalidInfoThrow() throws Exception {
    JasminBuilder builder = new JasminBuilder(ClassFileVersion.JDK_1_4);
    JasminBuilder.ClassBuilder clazz = builder.addClass("Test");

    clazz.addStaticMethod("foo", ImmutableList.of("I"), "V",
        ".limit stack 3",
        ".limit locals 4",
        ".var 0 is x I from LabelInit to LabelExit",
        ".var 1 is y I from LabelLocalStart to LabelExit",
        ".var 2 is e Ljava/lang/Exception; from LabelCatchStart to LabelCatchEnd",
        // var 3 is the jsr address
        "LabelInit:",
        "LabelTryStart:",
        "  ldc 84",
        "  iload 0",
        "  dup",
        "  istore 1", // init local[1] to value of local[0] (eg, 'x' since 'y' is not live yet).
        "  idiv",
        "  istore 0",
        "LabelLocalStart:",
        "  jsr LabelPrint",
        "  goto LabelExit",
        "LabelTryEnd:",
        "LabelCatchStart:",
        "  astore 2",
        "  jsr LabelPrint",
        "  return", // y is not actually live here.
        "LabelCatchEnd:",
        "LabelPrint:",
        "  astore 3",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  iload 0",
        "  invokevirtual java/io/PrintStream/println(I)V",
        "  ret 3",
        "LabelExit:",
        "  return",
        ".catch java/lang/Exception from LabelTryStart to LabelTryEnd using LabelCatchStart"
    );

    clazz.addMainMethod(
        ".limit stack 1",
        ".limit locals 1",
        "  ldc 2",
        "  invokestatic Test/foo(I)V",
        "  ldc 0",
        "  invokestatic Test/foo(I)V",
        "  return");

    String expected = "42" + ToolHelper.LINE_SEPARATOR + "0" + ToolHelper.LINE_SEPARATOR;
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClassFileData(builder.buildClasses())
          .run(parameters.getRuntime(), clazz.name)
          .assertSuccessWithOutput(expected);
    }
    testForD8(parameters.getBackend())
        .addProgramClassFileData(builder.buildClasses())
        .setMinApi(parameters.getApiLevel())
        .addOptionsModification(this::optionsModification)
        .compileWithExpectedDiagnostics(
            diagnostics -> {
              if (strict) {
                assertUninitializedLocalMessage(diagnostics);
              } else {
                diagnostics.assertNoMessages();
              }
            })
        .run(parameters.getRuntime(), clazz.name)
        .assertSuccessWithOutput(expected);
  }

  // Regression test to check that we properly add UninitializedLocal SSA values for methods that
  // have arguments without local info. To witness this bug, we also need "invalid" debug info, eg,
  // in this test the scope of "y" (local 2) spans the exceptional edge in which it is not live.
  @Test
  public void testInvalidInfoBug37722432() throws Exception {
    JasminBuilder builder = new JasminBuilder(ClassFileVersion.JDK_1_4);
    JasminBuilder.ClassBuilder clazz = builder.addClass("Test");

    clazz.addStaticMethod("foo", ImmutableList.of("I", "I"), "V",
        ".limit stack 2",
        ".limit locals 3",
        ".var 0 is x I from LabelInit to LabelExit",
        // Synthesized arg (no local info)
        ".var 2 is y I from LabelLocalStart to LabelExit",
        ".catch java/lang/Exception from LabelInit to LabelCatch using LabelCatch",
        "LabelInit:", // Start of try block targets catch with a state excluding 'y'.
        "  ldc 84",
        "  iload 0",
        "  idiv",
        "  istore 2",
        "LabelLocalStart:",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  iload 2",
        "  invokevirtual java/io/PrintStream/println(I)V",
        "  return",
        "LabelCatch:", // Catch target appears to include 'y' but actually does not.
        "  pop",
        "  return",
        "LabelExit:"
    );

    clazz.addMainMethod(
        ".limit stack 2",
        ".limit locals 1",
        "  ldc 2",
        "  ldc 2",
        "  invokestatic Test/foo(II)V",
        "  ldc 0",
        "  ldc 0",
        "  invokestatic Test/foo(II)V",
        "  return");

    String expected = "42" + ToolHelper.LINE_SEPARATOR;
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClassFileData(builder.buildClasses())
          .run(parameters.getRuntime(), clazz.name)
          .assertSuccessWithOutput(expected);
    }
    testForD8(parameters.getBackend())
        .addProgramClassFileData(builder.buildClasses())
        .addOptionsModification(this::optionsModification)
        .setMinApi(parameters.getApiLevel())
        .compileWithExpectedDiagnostics(
            diagnostics -> {
              if (strict) {
                assertUninitializedLocalMessage(diagnostics);
              } else {
                diagnostics.assertNoMessages();
              }
            })
        .run(parameters.getRuntime(), clazz.name)
        .assertSuccessWithOutput(expected);
  }

  @Test
  public void invalidInfoBug63412730_onWrite() throws Throwable {
    JasminBuilder builder = new JasminBuilder();
    JasminBuilder.ClassBuilder clazz = builder.addClass("Test");
    MethodSignature method = clazz.addStaticMethod("bar", ImmutableList.of(), "V",
        ".limit stack 3",
        ".limit locals 2",
        ".var 1 is i I from LI to End",
        ".var 0 is f F from LF to End",
        "Init:",
        "  ldc 42",
        "  istore 0",
        ".line 1",
        "LI:",
        "  ldc 7.5",
        "  fstore 1",
        ".line 2",
        "LF:",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  dup",
        "  iload 0",
        "  invokevirtual java/io/PrintStream/println(I)V",
        "  fload 1",
        "  invokevirtual java/io/PrintStream/println(F)V",
        ".line 3",
        "  return",
        "End:");

    clazz.addMainMethod(
        ".limit stack 1",
        ".limit locals 1",
        "  invokestatic Test/bar()V",
        "  return");

    String expected = StringUtils.lines("42", "7.5");
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClassFileData(builder.buildClasses())
          .run(parameters.getRuntime(), clazz.name)
          .assertSuccessWithOutput(expected);
    }
    testForD8(parameters.getBackend())
        .addProgramClassFileData(builder.buildClasses())
        .setMinApi(parameters.getApiLevel())
        .addOptionsModification(this::optionsModification)
        .compileWithExpectedDiagnostics(
            diagnostics -> {
              if (strict) {
                assertUninitializedLocalMessage(diagnostics);
              } else {
                assertInvalidTypeMessage(diagnostics);
              }
            })
        .run(parameters.getRuntime(), clazz.name)
        .assertSuccessWithOutput(expected)
        .inspect(
            inspector ->
                assertFalse(inspector.clazz(clazz.name).method(method).hasLocalVariableTable()));
  }

  @Test
  public void invalidInfoBug63412730_onRead() throws Throwable {
    JasminBuilder builder = new JasminBuilder();
    JasminBuilder.ClassBuilder clazz = builder.addClass("Test");
    MethodSignature method = clazz.addStaticMethod("bar", ImmutableList.of(), "V",
        ".limit stack 3",
        ".limit locals 2",
        ".var 1 is i I from Locals to End",
        ".var 0 is f F from Locals to End",
        "Init:",
        "  ldc 42",
        "  istore 0",
        ".line 1",
        "  ldc 7.5",
        "  fstore 1",
        ".line 2",
        "Locals:",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  dup",
        "  iload 0",
        "  invokevirtual java/io/PrintStream/println(I)V",
        "  fload 1",
        "  invokevirtual java/io/PrintStream/println(F)V",
        ".line 3",
        "  return",
        "End:");

    clazz.addMainMethod(
        ".limit stack 1",
        ".limit locals 1",
        "  invokestatic Test/bar()V",
        "  return");

    String expected = StringUtils.lines("42", "7.5");
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClassFileData(builder.buildClasses())
          .run(parameters.getRuntime(), clazz.name)
          .assertSuccessWithOutput(expected);
    }
    testForD8(parameters.getBackend())
        .addProgramClassFileData(builder.buildClasses())
        .addOptionsModification(this::optionsModification)
        .setMinApi(parameters.getApiLevel())
        .compileWithExpectedDiagnostics(this::assertInvalidTypeMessage)
        .run(parameters.getRuntime(), clazz.name)
        .assertSuccessWithOutput(expected)
        .inspect(
            inspector ->
                assertFalse(inspector.clazz(clazz.name).method(method).hasLocalVariableTable()));
  }

  @Test
  public void invalidInfoBug63412730_onMove() throws Throwable {
    JasminBuilder builder = new JasminBuilder(ClassFileVersion.JDK_1_4);
    JasminBuilder.ClassBuilder clazz = builder.addClass("Test");
    MethodSignature method = clazz.addStaticMethod("bar", ImmutableList.of(), "V",
        ".limit stack 3",
        ".limit locals 2",
        ".var 1 is i I from LI to End",
        ".var 0 is j F from LJ to End",
        "Init:",
        "  ldc 42",
        "  istore 0",
        ".line 1",
        "LI:",
        "  ldc 0",
        "  ldc 0",
        "  ifeq LZ",
        "  ldc 75",
        "  istore 1",
        ".line 2",
        "LJ:",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  iload 1",
        "  invokevirtual java/io/PrintStream/println(I)V",
        ".line 3",
        "  return",
        "LZ:",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  iload 0",
        "  invokevirtual java/io/PrintStream/println(I)V",
        ".line 4",
        "  return",
        "End:");

    clazz.addMainMethod(
        ".limit stack 1",
        ".limit locals 1",
        "  invokestatic Test/bar()V",
        "  return");

    String expected = StringUtils.lines("42");
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClassFileData(builder.buildClasses())
          .run(parameters.getRuntime(), clazz.name)
          .assertSuccessWithOutput(expected);
    }
    testForD8(parameters.getBackend())
        .addProgramClassFileData(builder.buildClasses())
        .addOptionsModification(this::optionsModification)
        .setMinApi(parameters.getApiLevel())
        .compileWithExpectedDiagnostics(
            diagnostics -> {
              if (strict) {
                assertUninitializedLocalMessage(diagnostics);
              } else {
                assertInvalidTypeMessage(diagnostics);
              }
            })
        .run(parameters.getRuntime(), clazz.name)
        .assertSuccessWithOutput(expected)
        .inspect(
            inspector ->
                assertFalse(inspector.clazz(clazz.name).method(method).hasLocalVariableTable()));
  }

  @Test
  public void invalidInfoBug63412730_onPop() throws Throwable {
    JasminBuilder builder = new JasminBuilder();
    JasminBuilder.ClassBuilder clazz = builder.addClass("Test");
    MethodSignature method = clazz.addStaticMethod("bar", ImmutableList.of(), "V",
        ".limit stack 3",
        ".limit locals 2",
        ".var 1 is a [Ljava/lang/Object; from Locals to End",
        ".var 0 is o LObject; from Locals to End",
        "Init:",
        "  ldc 1",
        "  anewarray java/lang/Object",
        "  astore 0",
        ".line 1",
        "  new java/lang/Integer",
        "  dup",
        "  ldc 42",
        "  invokespecial java/lang/Integer/<init>(I)V",
        "  astore 1",
        ".line 2",
        "Locals:",
        "  aload 0",
        "  ldc 0",
        "  aload 1",
        "  aastore",
        ".line 3",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  aload 0",
        "  ldc 0",
        "  aaload",
        "  invokevirtual java/io/PrintStream/println(Ljava/lang/Object;)V",
        ".line 4",
        "  return",
        "End:");

    clazz.addMainMethod(
        ".limit stack 1",
        ".limit locals 1",
        "  invokestatic Test/bar()V",
        "  return");

    String expected = StringUtils.lines("42");
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClassFileData(builder.buildClasses())
          .run(parameters.getRuntime(), clazz.name)
          .assertSuccessWithOutput(expected);
    }
    testForD8(parameters.getBackend())
        .addProgramClassFileData(builder.buildClasses())
        .addOptionsModification(this::optionsModification)
        .setMinApi(parameters.getApiLevel())
        .compileWithExpectedDiagnostics(TestDiagnosticMessages::assertNoMessages)
        .run(parameters.getRuntime(), clazz.name)
        .assertSuccessWithOutput(expected)
        .inspect(
            inspector -> {
              // Note: This code is actually invalid debug info, but we do not reject it because
              // both types are reference types. If we change that we should update this test.
              assertTrue(inspector.clazz(clazz.name).method(method).hasLocalVariableTable());
            });
  }
}
