Include preamble position in single-line judgment.

Bug: b/232212653
Change-Id: Ic4453deab0fbdef2106f66c8ff5e4970bacca637
diff --git a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
index f277168..86b7c35 100644
--- a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
@@ -6,6 +6,7 @@
 import com.android.tools.r8.ResourceException;
 import com.android.tools.r8.cf.code.CfInstruction;
 import com.android.tools.r8.cf.code.CfPosition;
+import com.android.tools.r8.code.Instruction;
 import com.android.tools.r8.debuginfo.DebugRepresentation.DebugRepresentationPredicate;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
@@ -1139,6 +1140,7 @@
     EventBasedDebugInfo debugInfo =
         DexDebugInfo.convertToEventBased(dexCode, appView.dexItemFactory());
     assert debugInfo != null;
+    IntBox firstDefaultEventPc = new IntBox(-1);
     BooleanBox singleOriginalLine = new BooleanBox(true);
     Pair<Integer, Position> lastPosition = new Pair<>();
     DexDebugEventVisitor visitor =
@@ -1149,6 +1151,9 @@
           public void visit(Default defaultEvent) {
             super.visit(defaultEvent);
             assert getCurrentLine() >= 0;
+            if (firstDefaultEventPc.get() < 0) {
+              firstDefaultEventPc.set(getCurrentPc());
+            }
             Position currentPosition = getPositionFromPositionState(this);
             if (lastPosition.getSecond() != null) {
               if (singleOriginalLine.isTrue()
@@ -1172,6 +1177,20 @@
       event.accept(visitor);
     }
 
+    // If the method has a single non-preamble line, check that the preamble is not active on any
+    // throwing instruction before the single line becomes active.
+    if (singleOriginalLine.isTrue() && firstDefaultEventPc.get() > 0) {
+      for (Instruction instruction : dexCode.instructions) {
+        if (instruction.getOffset() < firstDefaultEventPc.get()) {
+          if (instruction.canThrow()) {
+            singleOriginalLine.set(false);
+          }
+        } else {
+          break;
+        }
+      }
+    }
+
     int lastInstructionPc = ArrayUtils.last(dexCode.instructions).getOffset();
     if (lastPosition.getSecond() != null) {
       remapAndAddForPc(
diff --git a/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java b/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java
index 921d4d9..f8e88c6 100644
--- a/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java
+++ b/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java
@@ -179,14 +179,12 @@
     StackTraceLine fooLine =
         isRuntimeWithPcAsLineNumberSupport() ? inputLine("foo", 1) : inputLine("foo", -1);
 
-    // TODO(b/232212653): Retracing builds with stripped line table will retrace incorrectly.
-    StackTraceLine barLine =
-        (isRuntimeWithPcAsLineNumberSupport() && customSourceFile)
-                || !isCompileWithPcAsLineNumberSupport()
-            ? inputLine("bar", 100)
-            : inputLine("bar", 0);
+    // TODO(b/232212653): Normal line-opt will cause a single-line mapping. Retrace should not
+    //  optimize that to mean it represents a single possible line. (<noline> should not match 1:x).
+    StackTraceLine barLine = parameters.isCfRuntime() ? inputLine("bar", 100) : inputLine("bar", 0);
 
     // TODO(b/232212653): The retracing in CF where the line table is preserved is incorrect.
+    //  same issue as for bar.
     StackTraceLine bazLine = parameters.isCfRuntime() ? inputLine("baz", 100) : inputLine("baz", 0);
 
     return StackTrace.builder()
@@ -218,16 +216,9 @@
             ? line(UNKNOWN_SOURCE_FILE, "foo", 1)
             : residualLine("foo", -1);
 
-    // TODO(b/232212653): If not using a custom source file, then the single line identification
-    //  strips the line table.
-    StackTraceLine barLine =
-        isRuntimeWithPcAsLineNumberSupport() && !customSourceFile
-            ? line(UNKNOWN_SOURCE_FILE, "bar", 0)
-            : residualLine("bar", customSourceFile ? 0 : -1);
-
     return StackTrace.builder()
         .add(fooLine)
-        .add(barLine)
+        .add(residualLine("bar", 0))
         .add(residualLine("baz", 0))
         .add(residualLine("main", 6))
         .build();