Add DebugInfoTest
Bug: 77522100
Change-Id: I3da8bceffc4bfe3eb6c4a16be64e263ccb209cde
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index dc0cd0f..42775d2 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.ProgramConsumer;
import com.android.tools.r8.StringConsumer;
import com.android.tools.r8.dex.Marker;
+import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.InvalidDebugInfoException;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
@@ -100,6 +101,8 @@
public boolean verbose = false;
// Silencing output.
public boolean quiet = false;
+ // Throw exception if there is a warning about invalid debug info.
+ public boolean invalidDebugInfoFatal = false;
// Hidden marker for classes.dex
private boolean hasMarker = false;
@@ -268,6 +271,9 @@
public void warningInvalidDebugInfo(
DexEncodedMethod method, Origin origin, InvalidDebugInfoException e) {
+ if (invalidDebugInfoFatal) {
+ throw new CompilationError("Fatal warning: Invalid debug info", e);
+ }
synchronized (warningInvalidDebugInfo) {
warningInvalidDebugInfo.computeIfAbsent(
origin, k -> new ArrayList<>()).add(new Pair<>(method, e.getMessage()));
diff --git a/src/test/java/com/android/tools/r8/cf/DebugInfoTest.java b/src/test/java/com/android/tools/r8/cf/DebugInfoTest.java
new file mode 100644
index 0000000..6e009e8
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/cf/DebugInfoTest.java
@@ -0,0 +1,27 @@
+// 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.cf;
+
+public class DebugInfoTest {
+
+ public static void main(String[] args) {
+ if (args.length > 0) {
+ arg = args.length % 2 == 0;
+ DebugInfoTest.method();
+ }
+ }
+
+ private static boolean arg;
+
+ private static void method() {
+ int intVar;
+ if (arg) {
+ float floatVar1 = 0f;
+ intVar = (int) floatVar1;
+ } else {
+ float floatVar2 = 0f;
+ intVar = (int) floatVar2;
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/cf/DebugInfoTestRunner.java b/src/test/java/com/android/tools/r8/cf/DebugInfoTestRunner.java
new file mode 100644
index 0000000..fed7637
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/cf/DebugInfoTestRunner.java
@@ -0,0 +1,68 @@
+// 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.cf;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.ClassFileConsumer;
+import com.android.tools.r8.CompilationMode;
+import com.android.tools.r8.ProgramConsumer;
+import com.android.tools.r8.R8Command;
+import com.android.tools.r8.R8Command.Builder;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.errors.InvalidDebugInfoException;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.ThrowingConsumer;
+import java.nio.file.Path;
+import org.junit.Test;
+
+public class DebugInfoTestRunner extends TestBase {
+ static final Class CLASS = DebugInfoTest.class;
+
+ @Test
+ public void test() throws Exception {
+ ProcessResult runInput =
+ ToolHelper.runJava(ToolHelper.getClassPathForTests(), CLASS.getCanonicalName());
+ assertEquals(0, runInput.exitCode);
+ Path out1 = temp.getRoot().toPath().resolve("out1.zip");
+ build(
+ builder -> builder.addClassProgramData(ToolHelper.getClassAsBytes(CLASS), Origin.unknown()),
+ new ClassFileConsumer.ArchiveConsumer(out1));
+ ProcessResult run1 = ToolHelper.runJava(out1, CLASS.getCanonicalName());
+ assertEquals(runInput.toString(), run1.toString());
+ Path out2 = temp.getRoot().toPath().resolve("out2.zip");
+ boolean invalidDebugInfo = false;
+ try {
+ build(builder -> builder.addProgramFiles(out1), new ClassFileConsumer.ArchiveConsumer(out2));
+ } catch (CompilationError e) {
+ invalidDebugInfo = e.getCause() instanceof InvalidDebugInfoException;
+ }
+ // TODO(b/77522100): Change to assertFalse when fixed.
+ assertTrue(invalidDebugInfo);
+ if (!invalidDebugInfo) {
+ ProcessResult run2 = ToolHelper.runJava(out2, CLASS.getCanonicalName());
+ assertEquals(runInput.toString(), run2.toString());
+ }
+ }
+
+ private void build(ThrowingConsumer<Builder, Exception> input, ProgramConsumer consumer)
+ throws Exception {
+ Builder builder =
+ R8Command.builder()
+ .setMode(CompilationMode.DEBUG)
+ .addLibraryFiles(ToolHelper.getAndroidJar(ToolHelper.getMinApiLevelForDexVm()))
+ .setProgramConsumer(consumer);
+ input.accept(builder);
+ ToolHelper.runR8(
+ builder.build(),
+ o -> {
+ o.invalidDebugInfoFatal = true;
+ o.enableInlining = false;
+ });
+ }
+}