diff --git a/src/test/java/com/android/tools/r8/L8TestRunResult.java b/src/test/java/com/android/tools/r8/L8TestRunResult.java
index a9a9a78..8f6bab8 100644
--- a/src/test/java/com/android/tools/r8/L8TestRunResult.java
+++ b/src/test/java/com/android/tools/r8/L8TestRunResult.java
@@ -49,6 +49,12 @@
   }
 
   @Override
+  public <E extends Throwable> L8TestRunResult inspectFailure(
+      ThrowingConsumer<CodeInspector, E> consumer) {
+    throw new Unimplemented();
+  }
+
+  @Override
   public L8TestRunResult disassemble() throws IOException, ExecutionException {
     throw new Unimplemented();
   }
diff --git a/src/test/java/com/android/tools/r8/ProguardTestRunResult.java b/src/test/java/com/android/tools/r8/ProguardTestRunResult.java
index 3c2bbfc..c5cccbe 100644
--- a/src/test/java/com/android/tools/r8/ProguardTestRunResult.java
+++ b/src/test/java/com/android/tools/r8/ProguardTestRunResult.java
@@ -12,7 +12,6 @@
 import com.android.tools.r8.utils.ThrowingConsumer;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import java.io.IOException;
-import java.util.concurrent.ExecutionException;
 
 public class ProguardTestRunResult extends SingleTestRunResult<ProguardTestRunResult> {
 
@@ -34,14 +33,8 @@
     return super.getStackTrace().retrace(proguardMap);
   }
 
-  public StackTrace getOriginalStackTrace() {
-    return super.getStackTrace();
-  }
-
   @Override
-  public CodeInspector inspector() throws IOException, ExecutionException {
-    // See comment in base class.
-    assertSuccess();
+  protected CodeInspector internalGetCodeInspector() throws IOException {
     assertNotNull(app);
     return new CodeInspector(app, proguardMap);
   }
diff --git a/src/test/java/com/android/tools/r8/R8TestRunResult.java b/src/test/java/com/android/tools/r8/R8TestRunResult.java
index 3ef4901..716971d 100644
--- a/src/test/java/com/android/tools/r8/R8TestRunResult.java
+++ b/src/test/java/com/android/tools/r8/R8TestRunResult.java
@@ -10,7 +10,6 @@
 import com.android.tools.r8.naming.retrace.StackTrace;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.ThrowingBiConsumer;
-import com.android.tools.r8.utils.ThrowingConsumer;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.graphinspector.GraphInspector;
 import java.io.IOException;
@@ -52,10 +51,6 @@
     return super.getStackTrace().retraceAllowExperimentalMapping(proguardMap);
   }
 
-  public StackTrace getOriginalStackTrace() {
-    return super.getStackTrace();
-  }
-
   @Override
   protected CodeInspector internalGetCodeInspector() throws IOException {
     assertNotNull(app);
@@ -63,12 +58,6 @@
   }
 
   public <E extends Throwable> R8TestRunResult inspectOriginalStackTrace(
-      ThrowingConsumer<StackTrace, E> consumer) throws E {
-    consumer.accept(getOriginalStackTrace());
-    return self();
-  }
-
-  public <E extends Throwable> R8TestRunResult inspectOriginalStackTrace(
       ThrowingBiConsumer<StackTrace, CodeInspector, E> consumer) throws E, IOException {
     consumer.accept(getOriginalStackTrace(), internalGetCodeInspector());
     return self();
diff --git a/src/test/java/com/android/tools/r8/SingleTestRunResult.java b/src/test/java/com/android/tools/r8/SingleTestRunResult.java
index 17546ee..726acbd 100644
--- a/src/test/java/com/android/tools/r8/SingleTestRunResult.java
+++ b/src/test/java/com/android/tools/r8/SingleTestRunResult.java
@@ -60,6 +60,10 @@
   }
 
   public StackTrace getStackTrace() {
+    return getOriginalStackTrace();
+  }
+
+  public StackTrace getOriginalStackTrace() {
     if (runtime.isDex()) {
       return StackTrace.extractFromArt(getStdErr(), runtime.asDex().getVm());
     } else {
@@ -129,6 +133,12 @@
     return self();
   }
 
+  public <E extends Throwable> RR inspectOriginalStackTrace(
+      ThrowingConsumer<StackTrace, E> consumer) throws E {
+    consumer.accept(getOriginalStackTrace());
+    return self();
+  }
+
   public RR disassemble(PrintStream ps) throws IOException, ExecutionException {
     ToolHelper.disassemble(app, ps);
     return self();
diff --git a/src/test/java/com/android/tools/r8/TestRunResult.java b/src/test/java/com/android/tools/r8/TestRunResult.java
index 90d4f75..bd5ad83 100644
--- a/src/test/java/com/android/tools/r8/TestRunResult.java
+++ b/src/test/java/com/android/tools/r8/TestRunResult.java
@@ -38,6 +38,9 @@
   public abstract <E extends Throwable> RR inspect(ThrowingConsumer<CodeInspector, E> consumer)
       throws IOException, ExecutionException, E;
 
+  public abstract <E extends Throwable> RR inspectFailure(
+      ThrowingConsumer<CodeInspector, E> consumer) throws IOException, E;
+
   public abstract RR disassemble() throws IOException, ExecutionException;
 
   public <E extends Throwable> RR apply(ThrowingConsumer<RR, E> fn) throws E {
diff --git a/src/test/java/com/android/tools/r8/TestRunResultCollection.java b/src/test/java/com/android/tools/r8/TestRunResultCollection.java
index e166be4..c5421ac 100644
--- a/src/test/java/com/android/tools/r8/TestRunResultCollection.java
+++ b/src/test/java/com/android/tools/r8/TestRunResultCollection.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.utils.Pair;
 import com.android.tools.r8.utils.ThrowingConsumer;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -57,6 +58,12 @@
     return inspectIf(Predicates.alwaysTrue(), consumer);
   }
 
+  @Override
+  public <E extends Throwable> RR inspectFailure(ThrowingConsumer<CodeInspector, E> consumer)
+      throws IOException, E {
+    throw new Unimplemented();
+  }
+
   public RR applyIf(Predicate<C> filter, Consumer<TestRunResult<?>> thenConsumer) {
     return applyIf(filter, thenConsumer, r -> {});
   }
diff --git a/src/test/java/com/android/tools/r8/naming/sourcefile/SourceFileAttributeCompatTest.java b/src/test/java/com/android/tools/r8/naming/sourcefile/SourceFileAttributeCompatTest.java
new file mode 100644
index 0000000..ac17f3c
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/sourcefile/SourceFileAttributeCompatTest.java
@@ -0,0 +1,197 @@
+// Copyright (c) 2021, 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.naming.sourcefile;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.ProguardVersion;
+import com.android.tools.r8.SingleTestRunResult;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.TestShrinkerBuilder;
+import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.naming.retrace.StackTrace.StackTraceLine;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import java.util.function.Supplier;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class SourceFileAttributeCompatTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withSystemRuntime().build();
+  }
+
+  public SourceFileAttributeCompatTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  private String getOriginalSourceFile() {
+    return new Exception().getStackTrace()[0].getFileName();
+  }
+
+  private void commonSetUp(TestShrinkerBuilder<?, ?, ?, ?, ?> builder) {
+    builder
+        .addProgramClasses(TestClass.class, SemiKept.class, NonKept.class)
+        .addKeepMainRule(TestClass.class)
+        .addKeepRules("-keep,allowshrinking class " + SemiKept.class.getName() + " { *; }");
+  }
+
+  private void checkSourceFileIsRemoved(SingleTestRunResult<?> result) throws Exception {
+    // TODO(b/202368282): We should likely emit a "default" source file attribute rather than strip.
+    checkSourceFile(result, null, null, null);
+  }
+
+  private void checkSourceFileIsOriginal(SingleTestRunResult<?> result) throws Exception {
+    String originalSourceFile = getOriginalSourceFile();
+    checkSourceFile(result, originalSourceFile, originalSourceFile, originalSourceFile);
+  }
+
+  private void checkSourceFile(
+      SingleTestRunResult<?> result, String keptValue, String semiKeptValue, String nonKeptValue)
+      throws Exception {
+    result.assertFailure();
+    result.inspectOriginalStackTrace(
+        stackTrace -> {
+          StackTraceLine nonKeptLine = stackTrace.get(0);
+          StackTraceLine semiKeptLine = stackTrace.get(1);
+          StackTraceLine keptLine = stackTrace.get(4);
+          assertEquals(getExpectedSourceFile(nonKeptValue), nonKeptLine.fileName);
+          assertEquals(getExpectedSourceFile(semiKeptValue), semiKeptLine.fileName);
+          assertEquals(getExpectedSourceFile(keptValue), keptLine.fileName);
+        });
+    result.inspectFailure(
+        inspector -> {
+          ClassSubject testClass = inspector.clazz(TestClass.class);
+          ClassSubject semiKept = inspector.clazz(SemiKept.class);
+          ClassSubject nonKept = inspector.clazz(NonKept.class);
+          assertEquals(keptValue, getSourceFileString(testClass));
+          assertEquals(semiKeptValue, getSourceFileString(semiKept));
+          assertEquals(nonKeptValue, getSourceFileString(nonKept));
+        });
+  }
+
+  private String getSourceFileString(ClassSubject subject) {
+    DexString sourceFile = subject.getDexProgramClass().getSourceFile();
+    return sourceFile == null ? null : sourceFile.toString();
+  }
+
+  private String getExpectedSourceFile(String expectedSourceFileValue) {
+    return expectedSourceFileValue == null ? "Unknown Source" : expectedSourceFileValue;
+  }
+
+  private <RR extends SingleTestRunResult<RR>> void testJustKeepMain(
+      TestShrinkerBuilder<?, ?, ?, RR, ?> builder, boolean fullMode) throws Exception {
+    // If the source file attribute is not kept then all compilers will strip it throughout.
+    commonSetUp(builder);
+    builder.run(parameters.getRuntime(), TestClass.class).apply(this::checkSourceFileIsRemoved);
+  }
+
+  private <RR extends SingleTestRunResult<RR>> void testDontObfuscate(
+      TestShrinkerBuilder<?, ?, ?, RR, ?> builder, boolean fullMode) throws Exception {
+    // If minification is off then compat compilers retain it, full mode will remove it.
+    commonSetUp(builder);
+    builder
+        .addKeepRules("-dontobfuscate")
+        .run(parameters.getRuntime(), TestClass.class)
+        .applyIf(fullMode, this::checkSourceFileIsRemoved, this::checkSourceFileIsOriginal);
+  }
+
+  private <RR extends SingleTestRunResult<RR>> void testDontOptimize(
+      TestShrinkerBuilder<?, ?, ?, RR, ?> builder, boolean fullMode) throws Exception {
+    // No effect from -dontoptimize
+    commonSetUp(builder);
+    builder
+        .addKeepRules("-dontoptimize")
+        .run(parameters.getRuntime(), TestClass.class)
+        .apply(this::checkSourceFileIsRemoved);
+  }
+
+  private <RR extends SingleTestRunResult<RR>> void testDontShrink(
+      TestShrinkerBuilder<?, ?, ?, RR, ?> builder, boolean fullMode) throws Exception {
+    // No effect from -dontshrink
+    commonSetUp(builder);
+    builder
+        .addKeepRules("-dontshrink")
+        .run(parameters.getRuntime(), TestClass.class)
+        .apply(this::checkSourceFileIsRemoved);
+  }
+
+  private <RR extends SingleTestRunResult<RR>> void testKeepSourceFileAttribute(
+      TestShrinkerBuilder<?, ?, ?, RR, ?> builder, boolean fullMode) throws Exception {
+    // If the source file attribute is kept, then PG and compat R8 will preserve it in original
+    // form for every input class. R8 will only preserve it for (soft) pinned classes. Others will
+    // be replaced by 'SourceFile'. The use of 'SourceFile' is to ensure VMs still print lines.
+    // TODO(b/202367773): R8 (non-compat) should rather replace it for all classes like line opt.
+    String originalSourceFile = getOriginalSourceFile();
+    String residualSourceFile = fullMode ? "SourceFile" : originalSourceFile;
+    commonSetUp(builder);
+    builder
+        .addKeepAttributeSourceFile()
+        .run(parameters.getRuntime(), TestClass.class)
+        .apply(
+            result ->
+                checkSourceFile(
+                    result, originalSourceFile, originalSourceFile, residualSourceFile));
+  }
+
+  private <RR extends SingleTestRunResult<RR>> void runAllTests(
+      Supplier<TestShrinkerBuilder<?, ?, ?, RR, ?>> builder, boolean fullMode) throws Exception {
+    testJustKeepMain(builder.get(), fullMode);
+    testDontObfuscate(builder.get(), fullMode);
+    testDontOptimize(builder.get(), fullMode);
+    testDontShrink(builder.get(), fullMode);
+    testKeepSourceFileAttribute(builder.get(), fullMode);
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    runAllTests(() -> testForR8(parameters.getBackend()), true);
+  }
+
+  @Test
+  public void testCompatR8() throws Exception {
+    runAllTests(() -> testForR8Compat(parameters.getBackend()), false);
+  }
+
+  @Test
+  public void testPG() throws Exception {
+    runAllTests(() -> testForProguard(ProguardVersion.V7_0_0).addDontWarn(getClass()), false);
+  }
+
+  static class NonKept {
+    @Override
+    public String toString() {
+      throw new RuntimeException("BOOM!");
+    }
+  }
+
+  static class SemiKept {
+    final Object o;
+
+    public SemiKept(Object o) {
+      this.o = o;
+    }
+
+    @Override
+    public String toString() {
+      return o.toString();
+    }
+  }
+
+  static class TestClass {
+    public static void main(String[] args) {
+      System.out.println(
+          System.nanoTime() > 0
+              ? new SemiKept(System.nanoTime() > 0 ? new NonKept() : null)
+              : null);
+    }
+  }
+}
