Merge "Test verification behavior of dex move instructions."
diff --git a/src/test/java/com/android/tools/r8/smali/DexMoveInstructionsTest.java b/src/test/java/com/android/tools/r8/smali/DexMoveInstructionsTest.java
new file mode 100644
index 0000000..c92b73b
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/smali/DexMoveInstructionsTest.java
@@ -0,0 +1,95 @@
+// Copyright (c) 2018, 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.ToolHelper.ProcessResult;
+import com.android.tools.r8.utils.DescriptorUtils;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Test;
+
+public class DexMoveInstructionsTest extends SmaliTestBase {
+
+ public static final String CLASS = "Test";
+
+ @Test
+ public void testValidObjectMoves() throws Throwable {
+ ProcessResult result = testMoves("ExpectedToPass", "Ljava/lang/String;", Arrays.asList(
+ "move-object",
+ "move-object/from16",
+ "move-object/16"));
+ assertEquals(result.toString(), 0, result.exitCode);
+ }
+
+ @Test
+ public void testInvalidObjectMoves() throws Throwable {
+ ProcessResult result = testMoves("ExpectedToFail", "Ljava/lang/String;", Arrays.asList(
+ "move",
+ "move/from16",
+ "move/16"));
+ assertEquals(result.toString(), 1, result.exitCode);
+ assertTrue("Did not find 'Verification error' in " + result.stderr,
+ result.stderr.contains("Verification error") || result.stderr.contains("VerifyError"));
+ }
+
+ @Test
+ public void testValidSingleMoves() throws Throwable {
+ ProcessResult result = testMoves("ExpectedToPass", "I", Arrays.asList(
+ "move",
+ "move/from16",
+ "move/16"));
+ assertEquals(result.toString(), 0, result.exitCode);
+ }
+
+ @Test
+ public void testInvalidSingleMoves() throws Throwable {
+ ProcessResult result = testMoves("ExpectedToFail", "I", Arrays.asList(
+ "move-object",
+ "move-object/from16",
+ "move-object/16"));
+ assertEquals(result.toString(), 1, result.exitCode);
+ assertTrue("Did not find 'Verification error' in " + result.stderr,
+ result.stderr.contains("Verification error") || result.stderr.contains("VerifyError"));
+ }
+
+ private ProcessResult testMoves(String clazz, String typeDesc, List<String> moveOps)
+ throws Throwable {
+ String typeName = DescriptorUtils.descriptorToJavaType(typeDesc);
+
+ SmaliBuilder builder = new SmaliBuilder(clazz);
+ int i = 0;
+ for (String moveOp : moveOps) {
+ builder.addStaticMethod(typeName, "test" + i++, Collections.singletonList(typeName),
+ 1,
+ " " + moveOp + " v0, p0",
+ typeDesc.startsWith("L") ? "return-object v0" : " return v0"
+ );
+ }
+
+ List<String> main = new ArrayList<>();
+ main.add(" sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;");
+ main.add(" const v2, 0");
+ i = 0;
+ for (String moveOp : moveOps) {
+ main.add(" invoke-static { v2 }, L" + clazz + ";->test" + i++
+ + "(" + typeDesc + ")" + typeDesc);
+ if (typeDesc.startsWith("L")) {
+ main.add(" move-result-object v1");
+ } else {
+ main.add(" move-result v1");
+ }
+ main.add(" invoke-virtual { v0, v1 }, Ljava/io/PrintStream;->print(" + typeDesc + ")V");
+ }
+ main.add(" return-void");
+ builder.addMainMethod(3, main.toArray(new String[0]));
+
+ return runOnArtRaw(builder.build(), clazz);
+ }
+}