diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReferencesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReferencesTests.g.cs
index 18b2351fb747af..dc32f972824b72 100644
--- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReferencesTests.g.cs
+++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReferencesTests.g.cs
@@ -57,6 +57,18 @@ public Task CopyWithLinkedWillHaveMethodDepsKept ()
return RunTest (allowMissingWarnings: true);
}
+ [Fact]
+ public Task MissingReferenceInUnusedCodePath ()
+ {
+ return RunTest (allowMissingWarnings: true);
+ }
+
+ [Fact]
+ public Task MissingReferenceInUsedCodePath ()
+ {
+ return RunTest (allowMissingWarnings: true);
+ }
+
[Fact]
public Task ReferencesAreRemovedWhenAllUsagesAreRemoved ()
{
diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/DeleteBeforeAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/DeleteBeforeAttribute.cs
new file mode 100644
index 00000000000000..99d3c99d4b606d
--- /dev/null
+++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/DeleteBeforeAttribute.cs
@@ -0,0 +1,17 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+
+namespace Mono.Linker.Tests.Cases.Expectations.Metadata;
+
+///
+/// Deletes a file before the linker is ran
+///
+[AttributeUsage (AttributeTargets.Class)]
+public class DeleteBeforeAttribute : BaseMetadataAttribute
+{
+ public DeleteBeforeAttribute (string fileName)
+ {
+ }
+}
diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/References/Dependencies/MissingAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/References/Dependencies/MissingAssembly.cs
new file mode 100644
index 00000000000000..315c35af13d7c1
--- /dev/null
+++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/References/Dependencies/MissingAssembly.cs
@@ -0,0 +1,9 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Mono.Linker.Tests.Cases.References.Dependencies;
+
+public class MissingAssembly
+{
+
+}
diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/References/MissingReferenceInUnusedCodePath.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/References/MissingReferenceInUnusedCodePath.cs
new file mode 100644
index 00000000000000..16d5de6bd45402
--- /dev/null
+++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/References/MissingReferenceInUnusedCodePath.cs
@@ -0,0 +1,24 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Metadata;
+using Mono.Linker.Tests.Cases.References.Dependencies;
+
+namespace Mono.Linker.Tests.Cases.References;
+
+[ExpectNonZeroExitCode (1)]
+[NoLinkedOutput]
+[SetupCompileBefore ("missing.dll", new[] { "Dependencies/MissingAssembly.cs" })]
+[DeleteBefore ("missing.dll")]
+public class MissingReferenceInUnusedCodePath
+{
+ public static void Main ()
+ {
+ }
+
+ private static void UnusedPath ()
+ {
+ typeof (MissingAssembly).ToString ();
+ }
+}
diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/References/MissingReferenceInUsedCodePath.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/References/MissingReferenceInUsedCodePath.cs
new file mode 100644
index 00000000000000..99477f01d68213
--- /dev/null
+++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/References/MissingReferenceInUsedCodePath.cs
@@ -0,0 +1,20 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Metadata;
+using Mono.Linker.Tests.Cases.References.Dependencies;
+
+namespace Mono.Linker.Tests.Cases.References;
+
+[ExpectNonZeroExitCode (1)]
+[NoLinkedOutput]
+[SetupCompileBefore ("missing.dll", new[] { "Dependencies/MissingAssembly.cs" })]
+[DeleteBefore ("missing.dll")]
+public class MissingReferenceInUsedCodePath
+{
+ public static void Main ()
+ {
+ typeof (MissingAssembly).ToString ();
+ }
+}
diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadataProvider.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadataProvider.cs
index ae2a1deb33f366..c9004af0a25733 100644
--- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadataProvider.cs
+++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadataProvider.cs
@@ -152,6 +152,13 @@ public virtual IEnumerable GetLinkAttributesFiles ()
.Select (GetSourceAndRelativeDestinationValue);
}
+ public IEnumerable GetDeleteBefore ()
+ {
+ return _testCaseTypeDefinition.CustomAttributes
+ .Where (attr => attr.AttributeType.Name == nameof (DeleteBeforeAttribute))
+ .Select (attr => (string)attr.ConstructorArguments[0].Value);
+ }
+
public virtual IEnumerable GetExtraLinkerReferences ()
{
var netcoreappDir = Path.GetDirectoryName (typeof (object).Assembly.Location);
diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseSandbox.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseSandbox.cs
index 98528ae8d4dc75..b83275e825cab0 100644
--- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseSandbox.cs
+++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseSandbox.cs
@@ -159,6 +159,9 @@ public virtual void PopulateFromExpectations (TestCaseMetadataProvider metadataP
foreach (var res in metadataProvider.GetLinkAttributesFiles ()) {
res.Source.FileMustExist ().Copy (InputDirectory.Combine (res.DestinationFileName));
}
+
+ foreach (var delete in metadataProvider.GetDeleteBefore ())
+ InputDirectory.Combine (delete).FileMustExist ().Delete ();
}
private static NPath GetExpectationsAssemblyPath ()