Merge "Force compiling without locals information for release mode"
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index d3347b9..95bfbc0 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
 
   // This field is accessed from release scripts using simple pattern matching.
   // Therefore, changing this field could break our release scripts.
-  public static final String LABEL = "1.5.4-dev";
+  public static final String LABEL = "1.5.5-dev";
 
   private Version() {
   }
@@ -25,4 +25,10 @@
   public static boolean isDev() {
     return LABEL.endsWith("-dev") || VersionProperties.INSTANCE.isEngineering();
   }
+
+  /** Returns current R8 version (with additional info) as a string. */
+  @SuppressWarnings("unused") // used by external tools to obtain R8 version
+  public static String getVersionString() {
+    return LABEL + " (" + VersionProperties.INSTANCE.getDescription() + ")";
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/graph/GraphLense.java b/src/main/java/com/android/tools/r8/graph/GraphLense.java
index bac74f6..5fd473f 100644
--- a/src/main/java/com/android/tools/r8/graph/GraphLense.java
+++ b/src/main/java/com/android/tools/r8/graph/GraphLense.java
@@ -724,6 +724,10 @@
       if (originalMethods.contains(targetMethod)) {
         return true;
       }
+      // Stop traversing upwards if we reach the Object.
+      if (holder == dexItemFactory.objectType) {
+        continue;
+      }
       DexClass clazz = originalApplication.definitionFor(holder);
       if (clazz != null) {
         worklist.add(clazz.superType);
diff --git a/src/main/keep.txt b/src/main/keep.txt
index 61b2b14..306a398 100644
--- a/src/main/keep.txt
+++ b/src/main/keep.txt
@@ -14,6 +14,7 @@
 -keep public class com.android.tools.r8.compatdx.CompatDx { public static void main(java.lang.String[]); }
 -keep public class com.android.tools.r8.dexfilemerger.DexFileMerger { public static void main(java.lang.String[]); }
 -keep public class com.android.tools.r8.dexsplitter.DexSplitter { public static void main(java.lang.String[]); }
+-keep public class com.android.tools.r8.Version { public static java.lang.String getVersionString(); }
 
 # JvmMetadataExtensions must be kept because it'll be used indirectly through java.util.ServiceLoader.
 -keep, allowobfuscation public class com.android.tools.r8.jetbrains.kotlinx.metadata.jvm.impl.JvmMetadataExtensions { public <init>(); }
diff --git a/src/test/java/com/android/tools/r8/shaking/UnusedTypeInThrowingTest.java b/src/test/java/com/android/tools/r8/shaking/UnusedTypeInThrowingTest.java
new file mode 100644
index 0000000..6a03a43
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/UnusedTypeInThrowingTest.java
@@ -0,0 +1,38 @@
+// Copyright (c) 2019, 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.shaking;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.TestBase;
+import java.io.IOException;
+import org.junit.Ignore;
+import org.junit.Test;
+
+class UnusedTypeInThrowing {
+
+  public static void main(String[] args) throws UnusedTypeInThrowingThrowable {
+    System.out.print("42");
+  }
+}
+
+class UnusedTypeInThrowingThrowable extends Throwable {}
+
+public class UnusedTypeInThrowingTest extends TestBase {
+
+  static final Class THROWABLE_CLASS = UnusedTypeInThrowingThrowable.class;
+  static final Class MAIN_CLASS = UnusedTypeInThrowing.class;
+
+  @Test
+  @Ignore("b/124019003")
+  public void testTypeIsMarkedAsLive() throws IOException, CompilationFailedException {
+    testForR8(Backend.CF)
+        .addProgramClasses(MAIN_CLASS)
+        .addProgramClasses(THROWABLE_CLASS)
+        .addKeepMainRule(MAIN_CLASS)
+        .addKeepRules("-keepattributes Exceptions")
+        .run(MAIN_CLASS)
+        .assertSuccessWithOutput("42");
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/shaking/UnusedTypeInThrowingTestRunner.java b/src/test/java/com/android/tools/r8/shaking/UnusedTypeInThrowingTestRunner.java
new file mode 100644
index 0000000..2bf42a1
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/UnusedTypeInThrowingTestRunner.java
@@ -0,0 +1,37 @@
+// Copyright (c) 2019, 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.shaking;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.CompilationMode;
+import com.android.tools.r8.TestBase;
+import com.google.common.collect.ImmutableList;
+import java.io.IOException;
+import java.nio.file.Path;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class UnusedTypeInThrowingTestRunner extends TestBase {
+
+  static final Class THROWABLE_CLASS = UnusedTypeInThrowingThrowable.class;
+  static final Class MAIN_CLASS = UnusedTypeInThrowingTest.class;
+
+  @Test
+  @Ignore("b/124019003")
+  public void testTypeIsMarkedAsLive() throws IOException, CompilationFailedException {
+    Path outDex = temp.newFile("out.zip").toPath();
+    testForR8(Backend.CF)
+        .addProgramClasses(MAIN_CLASS)
+        .addProgramClasses(THROWABLE_CLASS)
+        .addKeepMainRule(MAIN_CLASS)
+        .addKeepRules(ImmutableList.of("-keepattributes Exceptions"))
+        .setMode(CompilationMode.RELEASE)
+        .enableInliningAnnotations()
+        .minification(true)
+        .compile()
+        .run(MAIN_CLASS)
+        .assertSuccessWithOutput("42");
+  }
+}