Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJackson Schuster <36744439+jtschuster@users.noreply.github.com>2022-08-09 22:28:28 +0300
committerGitHub <noreply@github.com>2022-08-09 22:28:28 +0300
commitd9aebf322b9dd6dcea16576d886bffbbe15e902f (patch)
tree32c7446789f27a302cebea26f85d5a6b4b1c278d
parentfe3a96424d28fb5b1eee4ca8c7e1713aa37247a4 (diff)
Test that basic ref field operations don't crash linker (#2952)
Adds test to use ref fields in various ways to confirm that they don't cause the linker to crash.
-rw-r--r--eng/Versions.props3
-rw-r--r--test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs6
-rw-r--r--test/Mono.Linker.Tests.Cases/Basic/LinkerHandlesRefFields.cs174
-rw-r--r--test/Mono.Linker.Tests.Cases/Basic/UnusedFieldsOfStructsAreKept.cs18
4 files changed, 199 insertions, 2 deletions
diff --git a/eng/Versions.props b/eng/Versions.props
index 00ee5f20b..da0fd6ac2 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -9,7 +9,6 @@
<PreReleaseVersionLabel>1</PreReleaseVersionLabel>
</PropertyGroup>
<PropertyGroup>
- <UsingToolMicrosoftNetCompilers>true</UsingToolMicrosoftNetCompilers>
<!-- ilasm -->
<MicrosoftNETSdkILPackageVersion>7.0.0-rc.1.22407.4</MicrosoftNETSdkILPackageVersion>
<!-- see https://github.com/dotnet/runtime/issues/1338 -->
@@ -21,7 +20,7 @@
<MicrosoftDotNetApiCompatVersion>7.0.0-beta.22379.10</MicrosoftDotNetApiCompatVersion>
<MicrosoftDotNetCodeAnalysisVersion>6.0.0-beta.21271.1</MicrosoftDotNetCodeAnalysisVersion>
<MicrosoftCodeAnalysisCSharpCodeStyleVersion>3.10.0-2.final</MicrosoftCodeAnalysisCSharpCodeStyleVersion>
- <MicrosoftCodeAnalysisVersion>4.3.0-2.final</MicrosoftCodeAnalysisVersion>
+ <MicrosoftCodeAnalysisVersion>4.4.0-2.22379.3</MicrosoftCodeAnalysisVersion>
<MicrosoftCodeAnalysisCSharpAnalyzerTestingXunitVersion>1.0.1-beta1.*</MicrosoftCodeAnalysisCSharpAnalyzerTestingXunitVersion>
<MicrosoftCodeAnalysisBannedApiAnalyzersVersion>3.3.2</MicrosoftCodeAnalysisBannedApiAnalyzersVersion>
<!-- This controls the version of the cecil package, or the version of cecil in the project graph
diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs
index a6fd75c94..c5834582d 100644
--- a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs
+++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs
@@ -40,6 +40,12 @@ namespace ILLink.RoslynAnalyzer.Tests
}
[Fact]
+ public Task LinkerHandlesRefFields ()
+ {
+ return RunTest (allowMissingWarnings: true);
+ }
+
+ [Fact]
public Task MultiLevelNestedClassesAllRemovedWhenNonUsed ()
{
return RunTest (allowMissingWarnings: true);
diff --git a/test/Mono.Linker.Tests.Cases/Basic/LinkerHandlesRefFields.cs b/test/Mono.Linker.Tests.Cases/Basic/LinkerHandlesRefFields.cs
new file mode 100644
index 000000000..8717e220f
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/Basic/LinkerHandlesRefFields.cs
@@ -0,0 +1,174 @@
+// 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;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Helpers;
+
+namespace Mono.Linker.Tests.Cases.Basic
+{
+ /// <summary>
+ /// This test is only to ensure that the linker does not crash when programs use ref fields (new to dotnet 7). This test does not validate any expected behaviors around ref fields.
+ /// </summary>
+ [ExpectedNoWarnings]
+ [SkipKeptItemsValidation]
+ class LinkerHandlesRefFields
+ {
+ ref struct RS
+ {
+ public ref int i;
+ public ref double d;
+ public RS2 rs2;
+ public ref object obj;
+ public ref Type t;
+ public void MoveThis ()
+ {
+ this = new RS ();
+ }
+ }
+
+ ref struct RS2
+ {
+ public ref int i;
+ public ref double d;
+ public ref object obj;
+ public ref Type t;
+ public void MoveThis ()
+ {
+ this = new RS2 ();
+ }
+ }
+
+ ref struct RsAnnotations
+ {
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public ref Type tDam;
+
+ [RequiresUnreferencedCode ("message for " + nameof (RefReturnWithMethods_HasRuc))]
+ [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public static ref Type RefReturnWithMethods_HasRuc (ref RsAnnotations rs)
+ {
+ return ref rs.tDam;
+ }
+ }
+
+ interface IRS
+ {
+ void RSParam (ref RS rsRef, RS rs);
+ RS RSReturn ();
+ ref RS2 RSParamAndReturn (ref RS rs);
+ }
+
+ class Base : IRS
+ {
+ public virtual void RSParam (ref RS rsRef, RS rs) { }
+ public virtual RS RSReturn () { return new RS (); }
+ public virtual ref RS2 RSParamAndReturn (ref RS rs)
+ {
+ return ref rs.rs2;
+ }
+ }
+
+ class Derived : Base, IRS
+ {
+ public override void RSParam (ref RS rsRef, RS rs) { }
+ public override RS RSReturn () { return new RS (); }
+ }
+
+ static void TestVirtualMethods ()
+ {
+ typeof (Base).RequiresPublicMethods ();
+ typeof (Derived).RequiresPublicMethods ();
+ }
+
+ // Ref structs can't implement interfaces
+
+ delegate RS2 RsParamRs2Return (RS rs);
+ delegate ref RS2 RefRSParamRefRs2Return (ref RS rs);
+ delegate ref int RsParamRefIntReturn (RS rs);
+
+ [ExpectedWarning ("IL2026", "message for " + nameof (RsAnnotations.RefReturnWithMethods_HasRuc))]
+ static void CallAnnotatedMethod ()
+ {
+ RsAnnotations rsa = new RsAnnotations ();
+ RsAnnotations.RefReturnWithMethods_HasRuc (ref rsa);
+ }
+ public static void Main (string[] args)
+ {
+ scoped RS rs = new RS ();
+ scoped RS2 rs2 = new RS2 ();
+
+ // Assign by value
+ rs.i = rs2.i;
+ rs2.d = rs2.d;
+ rs.obj = rs2.obj;
+ rs2.t = rs.t;
+
+ // Assign by ref
+ rs.i = ref rs2.i;
+ rs2.d = ref rs2.d;
+ rs.obj = ref rs2.obj;
+ rs2.t = ref rs.t;
+
+ // Assign in different basic blocks
+ if (args[0] == "") {
+ rs.i = ref rs2.i;
+ rs.d = rs2.d;
+ rs.obj = ref rs2.obj;
+ rs.t = rs2.t;
+ } else {
+ rs2.i = rs.i;
+ rs2.d = ref rs.d;
+ rs2.obj = rs.obj;
+ rs2.t = ref rs.t;
+ }
+
+ // Cast fields
+ rs.t = (Type) rs.obj;
+ rs.i = (int) rs.d;
+ rs2.i = (int) rs.d;
+
+ // In Lambdas
+ RsParamRs2Return f = (RS rs) => rs.rs2;
+ rs.rs2 = f (rs);
+ RefRSParamRefRs2Return h = (ref RS rs) => ref rs.rs2;
+ rs.rs2 = h (ref rs);
+ RsParamRefIntReturn g = (RS rs) => ref f (rs).i;
+ rs.i = g (rs);
+
+ // As parameters and returns for local functions
+ RS LocalMethod (RS2 rs)
+ {
+ rs.d = 0.2;
+ return new RS ();
+ }
+ rs = LocalMethod (rs.rs2);
+
+ ref RS LocalMethodRef (ref RS rs)
+ {
+ return ref rs;
+ }
+ ref RS refRs = ref LocalMethodRef (ref rs);
+ refRs = LocalMethodRef (ref rs);
+
+ ref int ReturnRefInt (ref int i)
+ {
+ return ref i;
+ }
+ rs.i = ReturnRefInt (ref rs2.i);
+
+ // Call methods with this
+ rs.MoveThis ();
+ rs2.MoveThis ();
+
+ CallAnnotatedMethod ();
+ TestVirtualMethods ();
+ }
+ }
+}
diff --git a/test/Mono.Linker.Tests.Cases/Basic/UnusedFieldsOfStructsAreKept.cs b/test/Mono.Linker.Tests.Cases/Basic/UnusedFieldsOfStructsAreKept.cs
index fb300fe6a..ff4bb5ae9 100644
--- a/test/Mono.Linker.Tests.Cases/Basic/UnusedFieldsOfStructsAreKept.cs
+++ b/test/Mono.Linker.Tests.Cases/Basic/UnusedFieldsOfStructsAreKept.cs
@@ -1,3 +1,5 @@
+using System;
+using System.Runtime.CompilerServices;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
namespace Mono.Linker.Tests.Cases.Basic
@@ -8,6 +10,7 @@ namespace Mono.Linker.Tests.Cases.Basic
{
A a = new A ();
PreventCompilerOptimization (a);
+ R r = new R ();
}
[Kept]
@@ -27,5 +30,20 @@ namespace Mono.Linker.Tests.Cases.Basic
{
}
}
+
+ [KeptAttributeAttribute (typeof (IsByRefLikeAttribute))]
+ [KeptAttributeAttribute (typeof (CompilerFeatureRequiredAttribute))]
+ [KeptAttributeAttribute (typeof (ObsoleteAttribute))]
+ ref struct R
+ {
+ [Kept]
+ public ref int UnusedRefField;
+
+ [Kept]
+ int UnusedField;
+
+ [Kept]
+ int UsedField;
+ }
}
} \ No newline at end of file