// Copyright (c) 2016, 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.smali;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Phi;
import com.android.tools.r8.ir.code.Return;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.smali.SmaliBuilder.MethodSignature;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import java.util.Arrays;
import java.util.Collections;
import org.junit.Test;

/**
 * Regression test to ensure that we do not ignore the exceptional / on-throw value of a
 * throwing instruction in the special case where the exceptional edge and the normal edge target
 * the same block.
 */
public class CatchSuccessorFallthroughTest extends SmaliTestBase {

  @Test
  public void catchSuccessorFallthroughTest() throws Exception {

    SmaliBuilder builder = new SmaliBuilder("Test");

    builder.addStaticMethod("int", "maybeThrow", Arrays.asList("int"), 0,
        "  if-eqz v0, :throw",
        "  const v0, 42",
        "  return v0",
        ":throw",
        "  div-int/2addr v0, v0",
        "  return v0");

    MethodSignature methodSig = builder.addStaticMethod(
        "int", "method", Collections.singletonList("int"), 0,
        ":try_start",
        "  invoke-static {v0}, LTest;->maybeThrow(I)I",
        "  move-result v0",
        ":try_end",
        "  .catch Ljava/lang/Throwable; {:try_start .. :try_end} :return",
        ":return",
        "  return v0"
    );

    builder.addStaticMethod(
        "void", "main", Arrays.asList("java.lang.String[]"), 2,
        "  sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "  const v0, 1",
        "  invoke-static {v0}, LTest;->method(I)I",
        "  move-result v0",
        "  invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(I)V",
        "  const v0, 0",
        "  invoke-static {v0}, LTest;->method(I)I",
        "  move-result v0",
        "  invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(I)V",
        "  return-void");

    AndroidApp originalApplication = buildApplication(builder);
    DexApplication application =
        new ApplicationReader(
                originalApplication,
                new InternalOptions(),
                new Timing("CatchSuccessorFallthroughTest"))
            .read();

    DexEncodedMethod method = getMethod(originalApplication, methodSig);
    // Get the IR pre-optimization.
    IRCode code =
        method.buildIR(
            new AppInfo(application),
            GraphLense.getIdentityLense(),
            new InternalOptions(),
            Origin.unknown());

    // Find the exit block and assert that the value is a phi merging the exceptional edge
    // with the normal edge.
    boolean hasReturn = false;
    for (BasicBlock block : code.blocks) {
      if (block.exit() instanceof Return) {
        // Find the return block.
        // Check it has one phi with two operands / two predecessors.
        Return ret = block.exit().asReturn();
        assertEquals(2, block.getPredecessors().size());
        assertEquals(1, block.getPhis().size());
        assertEquals(ret.returnValue(), block.getPhis().get(0));
        // Next we find and check that the phi values come from the expected predecessor.
        boolean hasNormalPredecessor = false;
        boolean hasExceptionalPredecessor = false;
        Phi phi = block.getPhis().get(0);
        for (Value operand : phi.getOperands()) {
          BasicBlock defBlock = operand.definition.getBlock();
          if (defBlock.canThrow()) {
            // Found the invoke instruction / block.
            assertEquals(2, defBlock.getSuccessors().size());
            assertTrue(
                defBlock.getInstructions().get(defBlock.getInstructions().size() - 2).isInvoke());
            for (BasicBlock returnPredecessor : block.getPredecessors()) {
              if (defBlock.hasCatchSuccessor(returnPredecessor)) {
                hasExceptionalPredecessor = true;
              } else if (defBlock == returnPredecessor) {
                // Normal flow goes to return.
                hasNormalPredecessor = true;
              } else if (defBlock.getSuccessors().contains(returnPredecessor)) {
                // Normal flow goes to return after an edge split.
                assertTrue(returnPredecessor.isTrivialGoto());
                hasNormalPredecessor = true;
              }
            }
          }
        }
        assertTrue(hasNormalPredecessor);
        assertTrue(hasExceptionalPredecessor);
        hasReturn = true;
      }
    }
    assertTrue(hasReturn);
  }
}
